diff --git a/TileCalorimeter/TileCalib/TileCalibBlobPython/python/TileCalibTools.py b/TileCalorimeter/TileCalib/TileCalibBlobPython/python/TileCalibTools.py
index 845106723ecb87f93271ae2c7e29f6ac72b2085c..f6fdfb80730b190c2b85016132651b64523434bf 100644
--- a/TileCalorimeter/TileCalib/TileCalibBlobPython/python/TileCalibTools.py
+++ b/TileCalorimeter/TileCalib/TileCalibBlobPython/python/TileCalibTools.py
@@ -13,11 +13,9 @@ Python helper module for managing COOL DB connections and TileCalibBlobs.
 
 from __future__ import print_function
 
-import ROOT
-
 import cx_Oracle # noqa: F401
 from PyCool import cool
-import time, re, sys, os
+import datetime, time, re, sys, os
 try:
     # For Python 3.0 and later
     from urllib.request import urlopen
@@ -591,7 +589,7 @@ class TileBlobWriter(TileCalibLogger):
             self.log().info( "... %d cool channels have been written in total (including comment field)", cnt )
 
     #____________________________________________________________________
-    def setComment(self, author, comment):
+    def setComment(self, author, comment=None):
         """
         Sets a general comment in the comment channel.
         """
@@ -603,12 +601,16 @@ class TileBlobWriter(TileCalibLogger):
                 data = cool.Record( spec )
                 self.__chanDictRecord[chanNum] = data
             blob = data['TileCalibBlob']
-            TileCalibDrawerCmt.getInstance(blob,author,comment)
+            if isinstance(author,tuple) and len(author)==3:
+                tm=time.mktime(datetime.datetime.strptime(author[2], "%a %b %d %H:%M:%S %Y").timetuple())
+                TileCalibDrawerCmt.getInstance(blob,author[0],author[1],int(tm))
+            else:
+                TileCalibDrawerCmt.getInstance(blob,author,comment)
         except Exception as e:
             self.log().critical( e )
         
     #____________________________________________________________________
-    def getComment(self):
+    def getComment(self, split=False):
         """
         Returns the general comment (default if none is set)
         """
@@ -619,7 +621,10 @@ class TileBlobWriter(TileCalibLogger):
                 return "<No general comment!>"
             blob = data['TileCalibBlob']
             cmt = TileCalibDrawerCmt.getInstance(blob)
-            return cmt.getFullComment()
+            if split:
+                return (cmt.getAuthor(),cmt.getComment(),cmt.getDate())
+            else:
+                return cmt.getFullComment()
         except Exception as e:
             self.log().critical( e )
 
@@ -734,7 +739,7 @@ class TileBlobReader(TileCalibLogger):
         self.__objDict = {}
 
     #____________________________________________________________________
-    def getComment(self, pointInTime):
+    def getComment(self, pointInTime, split=False):
         """
         Returns the general comment (default if none is set)
         """
@@ -745,7 +750,10 @@ class TileBlobReader(TileCalibLogger):
             self.log().debug("getComment:Fetching from DB: %s", obj)
             blob = obj.payload()[0]
             cmt = TileCalibDrawerCmt.getInstance(blob)
-            return cmt.getFullComment()
+            if split:
+                return (cmt.getAuthor(),cmt.getComment(),cmt.getDate())
+            else:
+                return cmt.getFullComment()
         except Exception:
             return "<no comment found>"
         
@@ -1145,20 +1153,26 @@ class TileASCIIParser(TileCalibLogger):
 class TileASCIIParser2(TileCalibLogger):
     """
     This is a class capable of parsing TileCal conditions data stored in
-    ASCII files. Both the single and multi-line formats are supported. 
+    ASCII files. This version of parser can be used when mutiple IOVs are
+    given in the file. First column is (run,lumi) pair in this case
     """
 
     #____________________________________________________________________
-    def __init__(self, fileName, calibId="", isSingleLineFormat=True):
+    def __init__(self, fileName, calibId="", readGain=True):
         """
         Input:
         - fileName          : input file name
-        - calibId           : like Ped, ...  but can be empty string as well
-        - isSingleLineFormat: if False, multi line format is assumed
+        - calibId           : like Ped, Las, ... or (r,l) or (run,lumi) but can be empty string as well
+        - readGain          : if False, no gain field in input file
         """
         
         TileCalibLogger.__init__(self,"TileASCIIParser2")
         self.__dataDict = {}
+        self.__manyIOVs = (calibId=="(run,lumi)" or calibId=="(r,l)" )
+        self.__readGain = readGain
+        iov=(0,0)
+        gain=-1
+
         try:
             lines = open(fileName,"r").readlines()
         except Exception as e:
@@ -1180,23 +1194,30 @@ class TileASCIIParser2(TileCalibLogger):
 
             #=== read in fields
             if len(calibId)>0:
-                type = fields[0]
+                pref = fields[0]
                 frag = fields[1]
                 chan = fields[2]
-                gain = fields[3]
-                data = fields[4:] 
+                if readGain:
+                    gain = fields[3]
+                    data = fields[4:]
+                else:
+                    data = fields[3:]
 
                 #=== check for correct calibId
-                if type!=calibId:
-                    raise Exception("%s is not calibId=%s" % (type,calibId))
+                if self.__manyIOVs:
+                    iov=tuple(int(i) for i in pref[1:-1].split(","))
+                    if len(iov)!=2 or pref[0]!="(" or pref[-1]!=")":
+                        raise Exception("%s is not %s IOV" % (pref,calibId))
+                elif pref!=calibId:
+                    raise Exception("%s is not calibId=%s" % (pref,calibId))
             else:
                 frag = fields[0]
                 chan = fields[1]
-                gain  = fields[2]
-                data = fields[3:] 
-
-            if not isSingleLineFormat:
-                raise Exception("Multiline format not implemented yet")
+                if readGain:
+                    gain  = fields[2]
+                    data = fields[3:]
+                else:
+                    data = fields[2:]
 
             #=== decode fragment 
             if frag.startswith('0x') or frag.startswith('-0x'):
@@ -1269,12 +1290,24 @@ class TileASCIIParser2(TileCalibLogger):
                      if allchannels or self.channel2PMT(ros,mod,chn)>0: 
                         for adc in range (adcmin,adcmax):
                            dictKey = (ros,mod,chn,adc)
-                           self.__dataDict[dictKey] = data
+                           if self.__manyIOVs:
+                               if dictKey in self.__dataDict:
+                                   self.__dataDict[dictKey] += [(iov,data)]
+                               else:
+                                   self.__dataDict[dictKey] = [(iov,data)]
+                           else:
+                               self.__dataDict[dictKey] = data
 
     #____________________________________________________________________
-    def getData(self, ros, drawer, channel, adc):
+    def getData(self, ros, drawer, channel, adc, iov=(MAXRUN,MAXLBK)):
         dictKey = (int(ros), int(drawer), int(channel), int(adc))
         data = self.__dataDict.get(dictKey,[])
+        if self.__manyIOVs and len(data)>0:
+            before= [i for i in sorted(data) if i[0] <= iov ]
+            if len(before)>0:
+                data = before[-1][1]
+            else:
+                data = []
         return data
 
     #____________________________________________________________________
@@ -1384,7 +1417,3 @@ class TileASCIIParser3(TileCalibLogger):
         import copy
         return copy.deepcopy(self.__dataDict)
 
-
-
-
-        
diff --git a/TileCalorimeter/TileCalib/TileCalibBlobPython/share/WriteCalibToCool.py b/TileCalorimeter/TileCalib/TileCalibBlobPython/share/WriteCalibToCool.py
index e1d2c5d1e4cade6ec9cba9baf23112348fa91536..815a68af43c41c64ebc5561cbe5021c9b700748d 100755
--- a/TileCalorimeter/TileCalib/TileCalibBlobPython/share/WriteCalibToCool.py
+++ b/TileCalorimeter/TileCalib/TileCalibBlobPython/share/WriteCalibToCool.py
@@ -326,10 +326,14 @@ ngainDef=ngain
 
 comments = []
 blobWriters = []
+nvalUpdated = []
+commentsSplit = []
 for since in iovList:
     comm=blobReader.getComment(since)
     log.info("Comment: %s", comm)
     comments+=[comm]
+    nvalUpdated += [0]
+    commentsSplit+=[blobReader.getComment(since,True)]
     blobWriters += [TileCalibTools.TileBlobWriter(dbw,outfolderPath,'Flt',(True if len(outtag) else False))]
 log.info( "\n" )
 
@@ -356,6 +360,7 @@ if len(txtFile)>0:
         nvold=0
         nvnew=0
         nvdef=0
+        nvnewdef=0
 
         #=== loop over whole detector
         irm=-1
@@ -383,12 +388,20 @@ if len(txtFile)>0:
                     modSpec = modName
                 newDrawer=True
                 flt1 = blobReader.getDrawer(ros, mod, since, False, False)
+                if flt1:
+                    oldNchan = flt1.getNChans()
+                    oldNgain = flt1.getNGains()
+                    oldVsize = flt1.getObjSizeUint32()
+                else:
+                    oldNchan = 0
+                    oldNgain = 0
+                    oldVsize = 0
                 nchan = nchanDef if nchanDef>0 else (flt1.getNChans() if flt1 else TileCalibUtils.max_chan())
                 ngain = ngainDef if ngainDef>0 else (flt1.getNGains() if flt1 else TileCalibUtils.max_gain())
                 for chn in range(nchan):
                     #=== loop over gains
                     for adc in range(ngain):
-                        data = blobParser.getData(ros,mod,chn,adc)
+                        data = blobParser.getData(ros,mod,chn,adc,since)
                         if not len(data) and allzero:
                             continue
                         if not len(data) and (not all or (not flt1 and not rosmin)):
@@ -431,6 +444,10 @@ if len(txtFile)>0:
                                         calibDrawer.setData(ch,ad,n,val)
                                         if undo:
                                             calibDrawer2.setData(ch,ad,n,val)
+                                    for n in range(kval,nval):
+                                        nvdef+=1
+                                        val=calibDrawer.getData(ch,ad,n)
+                                        log.debug("%i/%2i/%2i/%i: def data[%i] = %f", ros,mod,ch,ad, n, val)
 
                         if not len(data):
                             if not rosmin:
@@ -444,7 +461,8 @@ if len(txtFile)>0:
                         nnew+=1
                         kval=mval-len(data)
                         if kval>0:
-                            ndef+=1
+                            if chn>=oldNchan or adc>=oldNgain:
+                                ndef+=1
                             mval-=kval
                         for n in range(mval):
                             coef=None
@@ -475,13 +493,24 @@ if len(txtFile)>0:
                                 val = float(strval)
                             if val is not None:
                                 nvnew+=1
+                                if n>=oldVsize:
+                                    nvdef-=1
+                                    nvnewdef+=1
                                 calibDrawer.setData(chn,adc,n,val)
                                 if coef is None:
                                     log.debug("%i/%2i/%2i/%i: new data[%i] = %s", ros,mod,chn,adc, n, val)
+                            else:
+                                val = calibDrawer.getData(chn,adc,n)
+                                if n>=oldVsize:
+                                    log.debug("%i/%2i/%2i/%i: DEF data[%i] = %s", ros,mod,chn,adc, n, val)
+                                else:
+                                    log.debug("%i/%2i/%2i/%i: OLD data[%i] = %s", ros,mod,chn,adc, n, val)
                         for n in range(mval,kval+mval):
-                            nvdef+=1
                             val = calibDrawer.getData(chn,adc,n)
-                            log.debug("%i/%2i/%2i/%i: def data[%i] = %s", ros,mod,chn,adc, n, val)
+                            if n>=flt.getObjSizeUint32():
+                                log.debug("%i/%2i/%2i/%i: DEF data[%i] = %s", ros,mod,chn,adc, n, val)
+                            else:
+                                log.debug("%i/%2i/%2i/%i: OLD data[%i] = %s", ros,mod,chn,adc, n, val)
                 if (zero or allzero) and newDrawer:
                     blobWriters[io].zeroBlob(ros,mod)
                     if ros==0 and mod==0:
@@ -490,14 +519,15 @@ if len(txtFile)>0:
                         calibDrawer = blobWriters[io].getDrawer(ros,mod)
                         calibDrawer.init(defConst,1,blobVersion)
 
+        nvalUpdated[io]=nvnew
         log.info("%d/%d old channels*gains/values have been read from database", nold,nvold)
         log.info("%d/%d new channels*gains/values have been read from input ascii file", nnew,nvnew)
-        if nold>nnew or nvold>nvnew:
-            log.info("%d/%d old channels*gains/values remain unchanged", nold-nnew,nvold-nvnew)
-        if nold<nnew or nvold<nvnew:
-            log.info("%d/%d new channels*gains/values have been added to database", nnew-nold,nvnew-nvold)
-        if ndef:
-            log.info("%d/%d new channels*gains/values with default values have been added to database", ndef-nold,nvdef)
+        if nold>nnew or nvold>(nvnew-nvnewdef):
+            log.info("%d/%d old channels*gains/values remain unchanged", nold-nnew,nvold-nvnew+nvnewdef)
+        if nold<nnew or nvold<(nvnew-nvnewdef):
+            log.info("%d/%d new channels*gains/values have been added to database", nnew-nold,nvnew-nvold-nvnewdef)
+        if ndef or nvdef:
+            log.info("%d/%d new channels*gains/values with default values have been added to database", ndef,nvdef)
     
 #=== commit changes
 if mval!=0 and (len(comment)>0 or len(txtFile)>0):
@@ -517,7 +547,10 @@ if mval!=0 and (len(comment)>0 or len(txtFile)>0):
                 comm=comment
             if iov:
                 comm+=" - "+comments[io]
-            blobWriters[io].setComment(user,comm)
+            if iov and (nvalUpdated[io]==0 or comment=="keep"):
+                blobWriters[io].setComment(commentsSplit[io])
+            else:
+                blobWriters[io].setComment(user,comm)
         blobWriters[io].register(begin, until, outfolderTag)
     if undo:
         if (comment is None) or (comment == "None"):