ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/pymsxml/pymsxml.py
(Generate patch)
# Line 7 | Line 7
7   import tempfile
8   import csv
9   import gzip
10 < import zipfile
10 > import zlib
11   from array import array
12   from base64 import b64encode,b64decode
13   from urllib import quote,unquote
# Line 17 | Line 17
17      def __init__(self):
18          self.name_ = "PyMsXML"
19          self.majorVer = 0
20 <        self.minorVer = 4
21 <        self.revVer = 0
20 >        self.minorVer = 5
21 >        self.revVer = 4
22      def version(self):
23          return "%d.%d.%d"%(self.majorVer,self.minorVer,self.revVer)
24      def name(self):
# Line 36 | Line 36
36      return s.hexdigest().lower()
37  
38   class ToMzXML:
39 <    def __init__(self,reader,filename,cmpfmt=None,filt=None):
39 >    def __init__(self,reader,filename,cmpfmt=None,filt=None,peaksCompress=False,version="3.0"):
40          self.filename = filename
41          self.compressfmt = cmpfmt
42          self.reader = reader
# Line 45 | Line 45
45          self.actualScanCount = 0
46          self.scanIndices = {}
47          self.filter = filt
48 +        if not version in ('2.1','2.2','3.0'):
49 +            raise "Bad mzXML version \"%s\""%(version,)
50 +        self.version = version
51 +        if peaksCompress and float(self.version) < 3.0:
52 +            raise "Cannot compress peaks until mzXML version 3.0"
53 +        self.peakcompress = peaksCompress
54  
55      def __del__(self):
56          if hasattr(self,'tmpFileName') and self.tmpFileName and self.tmpFileName != '':
# Line 97 | Line 103
103          self.writeString (xmlFile,'<?xml version="1.0" encoding="ISO-8859-1"?>\n')
104    
105          outStr = "<mzXML "
106 <        outStr += "xmlns=\"http://sashimi.sourceforge.net/schema_revision/mzXML_2.1\" "
106 >        outStr += "xmlns=\"http://sashimi.sourceforge.net/schema_revision/mzXML_%s\" "%(self.version,)
107          outStr += "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
108 <        outStr += "xsi:schemaLocation=\"http://sashimi.sourceforge.net/schema_revision/mzXML_2.1 http://sashimi.sourceforge.net/schema_revision/mzXML_2.1/mzXML_idx_2.1.xsd\""
108 >        outStr += "xsi:schemaLocation=\"http://sashimi.sourceforge.net/schema_revision/mzXML_%s http://sashimi.sourceforge.net/schema_revision/mzXML_%s/mzXML_idx_%s.xsd\""%(self.version,self.version,self.version)
109          outStr += ">\n"
110  
111          self.writeString (xmlFile,outStr)
112    
113          outStr = "<msRun"
114          outStr += " scanCount=\"%d\"" % (self.actualScanCount,)
115 <        for (k,v) in self.reader.getMsRunMetaData().items():
115 >        md = self.reader.getMsRunMetaData()
116 >        for (k,v) in md.items():
117              k,f = k.split(':')
118 <            outStr += (" %%s=\"%s\""%(f,))%(k,v)
118 >            if self.version not in ('2.2',) or (k != 'startTime'and k != 'endTime'):
119 >                outStr += (" %%s=\"%s\""%(f,))%(k,v)
120          outStr += ">\n"
121  
122          self.writeString (xmlFile,outStr)
# Line 129 | Line 137
137                  outStr += "fileSha1=\"%s\""  % (f[2],)
138                  outStr += "/>\n"                
139              self.writeString (xmlFile,outStr)
140 <  
141 <        outStr = "<msInstrument>\n"
140 >
141 >        if float(self.version) >= 3.0:
142 >            outStr = "<msInstrument msInstrumentID=\"%s\">\n" % (self.reader.msInstrumentID(),)
143 >        else:
144 >            outStr = "<msInstrument>\n"
145 >            
146          outStr += "<msManufacturer category=\"msManufacturer\" value=\"%s\"/>\n" % (self.reader.msManufacturer(),)
147          outStr += "<msModel category=\"msModel\" value=\"%s\"/>\n" % (self.reader.msModel(),)
148          if self.reader.msIonisation():
# Line 179 | Line 191
191              outStr += "/>\n"
192              outStr += "<processingOperation "
193              outStr += "name=\"peak_detection_level_1_software\" "
194 <            outStr += "value=\"Analyst\""
194 >            outStr += "value=\"%s\""%(self.reader.acquisitionSoftware(),)
195              outStr += "/>\n"
196              self.writeString (xmlFile,outStr)
197          if (self.reader.peakDetect(2)):
# Line 193 | Line 205
205              outStr += "/>\n"
206              outStr += "<processingOperation "
207              outStr += "name=\"peak_detection_level_2_software\" "
208 <            outStr += "value=\"Analyst\""
208 >            outStr += "value=\"%s\""%(self.reader.acquisitionSoftware(),)
209              outStr += "/>\n"
210              self.writeString (xmlFile,outStr)
211  
# Line 357 | Line 369
369              outStr += ">\n"
370              self.writeString(xmlFile,outStr)
371  
372 +            if self.version in ('2.2',):
373 +                any = False
374 +                for (k,v) in d.items():
375 +                    if k.startswith('scanOrigin.'):
376 +                        if not any:
377 +                            any = True
378 +                            outStr = "<scanOrigin"
379 +                        k,f = k.split(':')
380 +                        k = k[11:]
381 +                        outStr += (" %%s=\"%s\""%(f,))%(k,v)
382 +                if any:
383 +                    outStr += "/>\n"
384 +                    self.writeString(xmlFile,outStr)
385 +
386              if msLevel > 1:
387  
388                  if not d.has_key('precursorMz') :
# Line 401 | Line 427
427                  outStr += "%f</precursorMz>\n" % (pMz,)
428                  self.writeString(xmlFile,outStr)
429  
430 <            if self.reader.maldi():
430 >            if self.reader.maldi() and self.version in ('2.2',):
431                  outStr = '<maldi'
432                  for (k,v) in d.items():
433                      if k.startswith('maldi.'):
# Line 413 | Line 439
439                  outStr += "/>\n"
440                  self.writeString(xmlFile,outStr)
441  
442 <            outStr = "<peaks precision=\"32\" byteOrder=\"network\" pairOrder=\"m/z-int\">"
442 >            if sys.byteorder != 'big':
443 >                s.byteswap()
444 >
445 >            if debug:
446 >                s = s[:20]
447 >
448 >            specstr = s.tostring()
449 >            if self.peakcompress:
450 >                specstr = zlib.compress(specstr,9)
451 >                outStr = "<peaks precision=\"32\" byteOrder=\"network\" contentType=\"m/z-int\" compressionType=\"zlib\" compressedLen=\"%d\">"%(len(specstr),)
452 >            else:
453 >                if float(self.version) >= 3.0:
454 >                    outStr = "<peaks precision=\"32\" byteOrder=\"network\" contentType=\"m/z-int\" compressionType=\"none\" compressedLen=\"%d\">"%(len(specstr),)
455 >                else:
456 >                    outStr = "<peaks precision=\"32\" byteOrder=\"network\" pairOrder=\"m/z-int\">"
457 >                    
458              self.writeString(xmlFile,outStr)
459  
460              # Spec says the byte order shall be
# Line 422 | Line 463
463              if sys.byteorder != 'big':
464                  s.byteswap()
465  
466 <            outStr = b64encode(s.tostring())
467 <            if not debug:
427 <                self.writeString(xmlFile,outStr)
428 <            else:
429 <                self.writeString(xmlFile,outStr[0:100])
430 <
431 <            if sys.byteorder != 'big':
432 <                s.byteswap()
466 >            outStr = b64encode(specstr)
467 >            self.writeString(xmlFile,outStr)
468  
469              outStr = "</peaks>\n"
470              self.writeString(xmlFile,outStr)
471  
472 <            if self.reader.maldi():
472 >            if self.reader.maldi() and self.version not in ('2.2',):
473                  outStr = ''
474                  for (k,v) in d.items():
475                      if k.startswith('maldi.'):
476                          k,f = k.split(':')
477                          k = k[6:]
478                          outStr += '<nameValue'
479 <                        outStr += ' name="%s"'%(k,)
480 <                        outStr += (' value="%f"'%(f,))%(v,)
479 >                        outStr += ' name="maldi.%s"'%(k,)
480 >                        outStr += (' value="%s"'%(f,))%(v,)
481                          outStr += '/>\n'
482 < ##              outStr += '<nameValue'
483 < ##              outStr += ' name="plateID"'
484 < ##              outStr += ' value="%s"'%(d['plateID'],)
485 < ##              outStr += '/>\n'
486 < ##              outStr += '<nameValue'
487 < ##              outStr += ' name="spotID"'
488 < ##              outStr += ' value="%s"'%(d['spotID'],)
489 < ##              outStr += '/>\n'
482 >                outStr += '<nameValue'
483 >                outStr += ' name="maldi.plateID"'
484 >                outStr += ' value="%s"'%(d['plateID'],)
485 >                outStr += '/>\n'
486 >                outStr += '<nameValue'
487 >                outStr += ' name="maldi.spotID"'
488 >                outStr += ' value="%s"'%(d['spotID'],)
489 >                outStr += '/>\n'
490 >                self.writeString(xmlFile,outStr)
491 >
492 >            if self.version not in ('2.2',):
493 >                outStr = ''
494 >                for (k,v) in d.items():
495 >                    if k.startswith('scanOrigin.'):
496 >                        k,f = k.split(':')
497 >                        k = k[11:]
498 >                        outStr += '<nameValue'
499 >                        outStr += ' name="scanOrigin.%s"'%(k,)
500 >                        outStr += (' value="%s"'%(f,))%(v,)
501 >                        outStr += '/>\n'
502 >                self.writeString(xmlFile,outStr)
503 >
504 >            outStr = ''
505 >            for (k,v) in d.items():
506 >                if k.startswith('nameValue.'):
507 >                    k,f = k.split(':')
508 >                    k = k[10:]
509 >                    outStr += '<nameValue'
510 >                    outStr += ' name="%s"'%(k,)
511 >                    outStr += (' value="%s"'%(f,))%(v,)
512 >                    outStr += '/>\n'
513 >            if len(outStr) > 0:
514                  self.writeString(xmlFile,outStr)
515  
516              xmlFile.flush()
# Line 459 | Line 518
518              prevSpec = s
519  
520          outStr = ""
521 <        for m in xrange(0,msLevel):
521 >        for m in xrange(0,len(ancestors)+1):
522              outStr += "</scan>\n"
523  
524          self.writeString(xmlFile,outStr)
# Line 812 | Line 871
871          self.theFMANSpecData = None
872          self.startTime = None
873          self.stopTime = None
874 +        self.applyPeakDetect = []
875          if peaks:
876              self.applyPeakDetect = map(int,peaks.split(','))
877  
# Line 907 | Line 967
967                              if self.peakDetect(msLevel):
968                                  peakDetect = 'True'
969                                  minY,maxY = self.theFMANSpecData.GetYValueRange()
970 <                                print minY,maxY
970 >                                # print minY,maxY
971                                  self.theFMANSpecData.Threshold(maxY*0.01)
972                                  self.theSPL.FindPeaksInDataObject(self.theFMANSpecData,50.0)
973                                  numPeaks = self.theSPL.GetNumberOfPeaks()
974 <                                print numPeaks
974 >                                # print numPeaks
975                                  for m in xrange(1,numPeaks+1):
976                                      (x,w,y,yp) = self.theSPL.GetPeak(m)
977                                      if y <= 0:
# Line 941 | Line 1001
1001  
1002                              # Scan level attributes
1003                              # Required by mzXML (no format spec. needed)
1004 <                            d = {'msLevel':msLevel,'scan.peakDetect:%s':peakDetect}
1004 >                            d = {'msLevel':msLevel}
1005                              # Optional ('scan.' and prefixformat spec. needed)
1006                              d.update({
1007                                  'scan.retentionTime:PT%fS':xValue,
1008                                  'scan.polarity:%s':polarity_val,
1009                                  'scan.startMz:%f':startMass,
1010                                  'scan.endMz:%f':stopMass,
951                                'scan.sample:%d':i,
952                                'scan.period:%d':j,
953                                'scan.experiment:%d':k,
954                                'scan.sampleName:%s':sampleName
1011                                  })
1012 <                            d.update({'scanOrigin.parentID:%s': self.filehash[f],
1012 >                            d.update({'scanOrigin.parentFileID:%s': self.filehash,
1013                                        'scanOrigin.num:%d': spectrumCount})
1014 +                            d.update({'nameValue.sample:%d':i,
1015 +                                      'nameValue.period:%d':j,
1016 +                                      'nameValue.experiment:%d':k,
1017 +                                      'nameValue.sampleName:%s':sampleName})
1018 +
1019                              if msLevel == 1:
1020                                  yield (dataArr,d)
1021                              else:
# Line 975 | Line 1036
1036      def getFilenames(self):
1037          return [ (self.filename,self.filehash) ]
1038  
1039 +    def msInstrumentID(self):
1040 +        return "1"
1041 +
1042      def msManufacturer(self):
1043          return "ABI / SCIEX"
1044  
# Line 1019 | Line 1083
1083          # print >>sys.stderr, ">>",self.context
1084          # sys.stderr.flush()
1085          if self.context.endswith(':msRun'):
1086 <            self.md['startTime'] = float(attrs['startTime'][2:-1])
1087 <            self.md['endTime'] = float(attrs['endTime'][2:-1])
1086 >            if attrs.has_key('startTime'):
1087 >                self.md['startTime'] = float(attrs['startTime'][2:-1])
1088 >            if attrs.has_key('endTime'):
1089 >                self.md['endTime'] = float(attrs['endTime'][2:-1])
1090          elif self.context.endswith(':parentFile'):
1091 <            self.md['fileName'] = unquote(attrs['fileName'])
1092 <            self.md['fileType'] = attrs['fileType']
1093 <            self.md['fileSha1'] = attrs['fileSha1']
1091 >            if not self.md.has_key('parentFile'):
1092 >                self.md['parentFile'] = []
1093 >            self.md['parentFile'].append((unquote(attrs['fileName']),attrs['fileType'],attrs['fileSha1']))
1094          elif self.context.endswith(':instrument'):
1095              self.md['msManufacturer'] = attrs['manufacturer']
1096              self.md['msModel'] = attrs['model']
# Line 1079 | Line 1145
1145              self.scannum = int(attrs['num'])
1146              if attrs.has_key('retentionTime'):
1147                  self.rt = float(attrs['retentionTime'][2:-1])
1148 <            self.endMz = float(attrs['endMz'])
1149 <            self.startMz = float(attrs['startMz'])
1148 >            if attrs.has_key('endMz'):
1149 >                self.endMz = float(attrs['endMz'])
1150 >            if attrs.has_key('startMz'):
1151 >                self.startMz = float(attrs['startMz'])
1152              self.polarity = attrs.get('polarity',None)
1153              for (k,v) in attrs.items():
1154                  self.scanmd[k] = v
# Line 1092 | Line 1160
1160              self.context = ':msRun'
1161          elif name == 'scanOrigin':
1162              self.scanmd['scanOrigin'] = attrs
1163 +        elif self.context.endswith(':scan:nameValue'):
1164 +            self.scanmd['nameValue.%s:%%s'%attrs['name']] = attrs['value']
1165              
1166      def characters(self, content):
1167          if self.scancount >= self.scanstart:
# Line 1103 | Line 1173
1173          if self.scancount >= self.scanstart:
1174              if self.context.endswith('scan:peaks'):
1175                  
1176 <                spec = array('f')
1176 >                self.spec = array('f')
1177                  # print >>sys.stderr, len(self.content), len(b64decode(self.content)), self.content
1178 <                spec.fromstring(b64decode(self.content))
1178 >                self.spec.fromstring(b64decode(self.content))
1179                  if sys.byteorder != 'big':
1180 <                    spec.byteswap()
1180 >                    self.spec.byteswap()
1181 >            elif self.context.endswith(':scan'):
1182                  d = {'msLevel':self.scanlevel}
1183                  # Optional ('scan.' and prefixformat spec. needed)
1184 <                d.update({
1185 <                    'scan.retentionTime:PT%fS':self.rt,
1186 <                    'scan.startMz:%f':self.startMz,
1187 <                    'scan.endMz:%f':self.endMz
1188 <                    })
1184 >                if hasattr(self,'rt'):
1185 >                    d.update({'scan.retentionTime:PT%fS':self.rt})
1186 >                if hasattr(self,'startMz'):
1187 >                    d.update({'scan.startMz:%f':self.startMz})
1188 >                if hasattr(self,'endMz'):
1189 >                    d.update({'scan.endMz:%f':self.endMz})
1190                  if self.polarity != None:
1191                      d.update({'scan.polarity:%s':self.polarity})
1192                  if self.scanlevel == 2:
1193                      d.update({'precursorMz':self.precursorMz})
1194                  if self.scanmd.has_key('scanOrigin'):
1195 <                    d.update({'scanOrigin.parentID:%s': self.scanmd['scanOrigin']['parentID'],
1196 <                              'scanOrigin.num:%d': self.scanmd['scanOrigin']['num']})
1195 >                    d.update({'scanOrigin.parentFileID:%s': self.scanmd['scanOrigin']['parentFileID'],
1196 >                              'scanOrigin.num:%d': int(self.scanmd['scanOrigin']['num'])})
1197                  for (k,v) in self.scanmd.items():
1198                      if not d.has_key(k):
1199                          d[k] = v
1200 <                self.spectra.append((spec,d))
1200 >                self.spectra.append((self.spec,d))
1201                  if len(self.spectra) >= self.scanmax:
1202                      self.scanstart = self.scancount+1
1203                      raise SAXException("Early termination")
# Line 1210 | Line 1282
1282  
1283      def getMsRunMetaData(self):
1284          self.open()
1285 <        d = {'startTime:PT%fS':self.md['startTime'],
1286 <             'endTime:PT%fS':self.md['endTime']
1287 <             }
1285 >        d = {}
1286 >        if self.md.has_key('startTime'):
1287 >            d.update({'startTime:PT%fS':self.md['startTime']})
1288 >        if self.md.has_key('endTime'):
1289 >            d.update({'endTime:PT%fS':self.md['endTime']})
1290          return d
1291  
1292      def getFilenames(self):
1293 <        return [ (self.md['fileName'],self.md['fileType'],self.md['fileSha1']) ]
1293 >        return self.md['parentFile']
1294 >
1295 >    def msInstrumentID(self):
1296 >        return "1"
1297 >
1298 >    def peakDetect(self,level):
1299 >        return False
1300  
1301      def msManufacturer(self):
1302          return self.md.get('msManufacturer','')
# Line 1274 | Line 1354
1354          # Probably unnecessary
1355          self.close()
1356  
1357 <    def open(self):
1357 >    def read_metadata(self):
1358 >                
1359 >        h = open(self.filename,'rb')
1360 >        r = csv.reader(h,'excel-tab')
1361  
1362 <        if self.deapp is None:
1362 >        self.metadata['PLATEDEF'] = []
1363 >        self.metadata['PLATE'] = []
1364 >        self.metadata['SPOT'] = []
1365 >        self.metadata['SCAN'] = []
1366  
1367 <            self.metadata['PLATEDEF'] = []
1368 <            self.metadata['PLATE'] = []
1369 <            self.metadata['SPOT'] = []
1370 <            self.metadata['SCAN'] = []
1371 <
1372 <            h = open(self.filename,'rb')
1373 <            r = csv.reader(h,'excel-tab')
1374 <            for l in r:
1375 <                if len(l) == 0:
1376 <                    continue
1377 <                kw = l.pop(0).upper()
1378 <                if kw in ('PLATEDEF','PLATE','SPOT','SCAN'):
1379 <                    self.metadata[kw].append({})
1380 <                    while len(l)>=2:
1381 <                        k = l.pop(0);v = l.pop(0);
1382 <                        if (kw == 'PLATE' and \
1383 <                            (k in ('plateID','spotXCount','spotYCount','plateManufacturer','plateModel'))) or \
1384 <                           (kw == 'PLATEDEF' and \
1385 <                            (k in ('plateID','plateManufacturer','plateModel','spotNaming','maldiMatrix'))) or \
1300 <                           (kw == 'SPOT' and \
1301 <                            (k in ('plateID','spotID','spotXPosition','spotYPosition','maldiMatrix'))) or \
1302 <                           (kw == 'SCAN' and \
1303 <                            (k in ('plateID','spotID','filename','index'))):
1304 <                            self.metadata[kw][-1][k] = v
1305 <                        elif k == '':
1306 <                            break
1307 <                        else:
1308 <                            print >>sys.stderr,"Bad key %s for %s row"%(k,kw)
1309 <                            sys.exit(1)
1310 <            h.close()
1311 <
1312 <            for pd in self.metadata['PLATEDEF']:
1313 <                # insert all the gory details needed for a particular plate model etc...
1314 <                if pd['plateManufacturer'] == 'ABI / SCIEX' and pd['plateModel'] == '01-192+06-BB':
1315 <                    if not pd.has_key('spotNaming') or not pd.has_key('maldiMatrix') or \
1316 <                       not pd['spotNaming'] in ('alpha','parallel','antiparallel'):
1317 <                        print >>sys.stderr,"Bad plate definition, missing maldiMatrix or spotNaming, or bad spotNaming value."
1318 <                        sys.exit(1)
1319 <                    self.metadata['PLATE'].append({
1320 <                        'plateID':pd['plateID'],
1321 <                        'plateManufacturer':pd['plateManufacturer'],
1322 <                        'plateModel':pd['plateModel'],
1323 <                        'spotXCount':24,
1324 <                        'spotYCount':8,
1325 <                        })
1326 <                    if pd['spotNaming'] == 'alpha':
1327 <                            for y in xrange(0,8):
1328 <                                for x in xrange(0,24):
1329 <                                    self.metadata['SPOT'].append({
1330 <                                        'plateID':pd['plateID'],
1331 <                                        'spotID':"%c%d"%(y+ord('A'),x+1),
1332 <                                        'spotXPosition':x,
1333 <                                        'spotYPosition':2*y+(x%2),
1334 <                                        'maldiMatrix':pd['maldiMatrix']
1335 <                                        })
1367 >        for l in r:
1368 >            if len(l) == 0:
1369 >                continue
1370 >            kw = l.pop(0).upper()
1371 >            if kw in ('PLATEDEF','PLATE','SPOT','SCAN'):
1372 >                self.metadata[kw].append({})
1373 >                while len(l)>=2:
1374 >                    k = l.pop(0);v = l.pop(0);
1375 >                    if (kw == 'PLATE' and \
1376 >                        (k in ('plateID','spotXCount','spotYCount','plateManufacturer','plateModel'))) or \
1377 >                       (kw == 'PLATEDEF' and \
1378 >                        (k in ('plateID','plateManufacturer','plateModel','spotNaming','maldiMatrix'))) or \
1379 >                       (kw == 'SPOT' and \
1380 >                        (k in ('plateID','spotID','spotXPosition','spotYPosition','maldiMatrix'))) or \
1381 >                       (kw == 'SCAN' and \
1382 >                        (k in ('plateID','spotID','filename','index'))):
1383 >                        self.metadata[kw][-1][k] = v
1384 >                    elif k == '':
1385 >                        break
1386                      else:
1387 <                        print >>sys.stderr,"Valid spotNaming value, not yet implemented."
1387 >                        print >>sys.stderr,"Bad key %s for %s row"%(k,kw)
1388                          sys.exit(1)
1389 +        h.close()
1390  
1391 <            for pl in self.metadata['PLATE']:
1392 <                self.platespots[pl['plateID']] = []
1391 >        for pd in self.metadata['PLATEDEF']:
1392 >            # insert all the gory details needed for a particular plate model etc...
1393 >            if pd['plateManufacturer'] == 'ABI / SCIEX' and pd['plateModel'] == '01-192+06-BB':
1394 >                if not pd.has_key('spotNaming') or not pd.has_key('maldiMatrix') or \
1395 >                   not pd['spotNaming'] in ('alpha','parallel','antiparallel'):
1396 >                    print >>sys.stderr,"Bad plate definition, missing maldiMatrix or spotNaming, or bad spotNaming value."
1397 >                    sys.exit(1)
1398 >                self.metadata['PLATE'].append({
1399 >                    'plateID':pd['plateID'],
1400 >                    'plateManufacturer':pd['plateManufacturer'],
1401 >                    'plateModel':pd['plateModel'],
1402 >                    'spotXCount':24,
1403 >                    'spotYCount':8,
1404 >                    })
1405 >                if pd['spotNaming'] == 'alpha':
1406 >                        for y in xrange(0,8):
1407 >                            for x in xrange(0,24):
1408 >                                self.metadata['SPOT'].append({
1409 >                                    'plateID':pd['plateID'],
1410 >                                    'spotID':"%c%d"%(y+ord('A'),x+1),
1411 >                                    'spotXPosition':x,
1412 >                                    'spotYPosition':2*y+(x%2),
1413 >                                    'maldiMatrix':pd['maldiMatrix']
1414 >                                    })
1415 >                else:
1416 >                    print >>sys.stderr,"Valid spotNaming value, not yet implemented."
1417 >                    sys.exit(1)
1418  
1419 <            for sp in self.metadata['SPOT']:
1420 <                self.platespots[sp['plateID']].append(sp)
1419 >        for pl in self.metadata['PLATE']:
1420 >            self.platespots[pl['plateID']] = []
1421  
1422 <            self.datafiles = [ (os.path.join(self.dir,md['filename']),int(md['index'])) for md in self.metadata['SCAN'] ]
1423 <            self.distinct_datafiles = dict([(os.path.join(self.dir,md['filename']),
1424 <                                            fileSHA(os.path.join(self.dir,md['filename']))) for md in self.metadata['SCAN']])
1425 <
1426 <            self.maptoscan = {}
1427 <            index = 0
1428 <            for md in self.metadata['SCAN']:
1429 <                self.maptoscan[(os.path.join(self.dir,md['filename']),int(md['index']))] = index
1430 <                index += 1
1422 >        for sp in self.metadata['SPOT']:
1423 >            self.platespots[sp['plateID']].append(sp)
1424 >
1425 >        self.datafiles = [ (os.path.join(self.dir,md['filename']),int(md['index'])) for md in self.metadata['SCAN'] ]
1426 >        self.distinct_datafiles = dict([(os.path.join(self.dir,md['filename']),
1427 >                                        fileSHA(os.path.join(self.dir,md['filename']))) for md in self.metadata['SCAN']])
1428 >
1429 >        self.maptoscan = {}
1430 >        index = 0
1431 >        for md in self.metadata['SCAN']:
1432 >            self.maptoscan[(os.path.join(self.dir,md['filename']),int(md['index']))] = index
1433 >            index += 1
1434 >
1435 >    def make_metadata(self):
1436 >        self.deapp.Documents.Open(self.filename)
1437 >        doc = self.deapp.Documents.Item(0)
1438 >        sv = doc.SpecView
1439 >        nspectra = sv.TotalSpectrum;
1440 >        self.deapp.Documents.Close()
1441 >        self.remsettingsfile(self.filename)
1442 >
1443 >        self.datafiles = [ (self.filename,i) for i in range(1,nspectra+1) ]
1444 >        self.distinct_datafiles = dict([ (self.filename, fileSHA(self.filename)) ])
1445 >        self.maptoscan = {}
1446 >        for (f,i) in self.datafiles:
1447 >            self.maptoscan[(f,i)] = i
1448 >            
1449 >    def open(self):
1450 >
1451 >        if self.deapp is None:
1452  
1453              from win32com.client import Dispatch, gencache
1454              self.deapp = Dispatch('DataExplorer.Application',
1455                                    resultCLSID='{3FED40F1-D409-11D1-8B56-0060971CB54B}')
1456              self.delib = gencache.EnsureModule('{06972F50-13F6-11D3-A5CB-0060971CB54B}',0,4,2)
1457 <            self.deapp.AutomatedProcessing = 1
1458 <            self.deapp.Visible             = 0
1457 >            try:
1458 >                self.deapp.AutomatedProcessing = 1
1459 >            except AttributeError:
1460 >                pass
1461 >            try:
1462 >                self.deapp.Visible = 0
1463 >            except AttributeError:
1464 >                pass
1465 >            
1466 >            try:
1467 >                self.read_metadata()
1468 >            except:
1469 >                self.make_metadata()
1470  
1471      def close(self):
1472  
# Line 1371 | Line 1479
1479  
1480   #   remove .set and .cts files to prevent DataExplorer crashes - DT 11-1-2006
1481      def remsettingsfile(self,fn):
1482 <
1483 <       if ((len(fn) > 3) and (fn[-4:].lower() == '.t2d')):
1484 <           path2del = fn[:-4] + '.cts'
1485 <           if os.path.exists(path2del):
1486 <               os.unlink(path2del)
1487 <           path2del = fn[:-4] + '.set'
1488 <           if os.path.exists(path2del):
1489 <               os.unlink(path2del)
1482 >        # print "rmsettingsfile: %s"%fn
1483 >        if ((len(fn) > 3) and (fn[-4:].lower() == '.t2d')):
1484 >            path2del = fn[:-4] + '.cts'
1485 >            if os.path.exists(path2del):
1486 >                os.unlink(path2del)
1487 >            path2del = fn[:-4] + '.set'
1488 >            if os.path.exists(path2del):
1489 >                os.unlink(path2del)
1490  
1491      def spectra(self):
1492          self.open()
# Line 1388 | Line 1496
1496  
1497              if f != prevfile:
1498                  self.deapp.Documents.Close()
1499 +                self.remsettingsfile(prevfile)
1500  
1501                  if not os.path.exists(f):
1502                      print >>sys.stderr, "Filename %s does not exist."%(f,)
1503                      sys.exit(1)
1504                  
1505                  self.remsettingsfile(f)
1397                self.remsettingsfile(prevfile)
1398
1506                  self.deapp.Documents.Open(f)
1507 +                # print "open %s"%f
1508  
1509 <            doc = self.deapp.Documents.Item(0)
1510 <            sv = doc.SpecView
1511 <
1509 >                doc = self.deapp.Documents.Item(0)
1510 >                sv = doc.SpecView
1511 >                try:
1512 >                    cv = doc.ChroView
1513 >                    cv.XAxisUnits = self.delib.constants.deChroXAxisTime
1514 >                    n,xaxis = cv.GetRawData(0,0)
1515 >                except:
1516 >                    xaxis = None
1517 >                
1518 >            if i > sv.TotalSpectrum:
1519 >                prevfile = f
1520 >                continue
1521 >            
1522              sv.SetSpectrumAt(i-1)
1523  
1524 +            if xaxis != None:
1525 +                retentionTime = xaxis[i-1][0]*60.0;
1526 +            else:
1527 +                retentionTime = None
1528              (tf,fixedMass) = doc.InstrumentSettings.GetSetting(self.delib.constants.dePreCursorIon,i-1,None)
1529                  
1530              if fixedMass > 0:
# Line 1440 | Line 1562
1562  
1563              # Scan level attributes
1564              # Required by mzXML (no format spec. needed)
1565 <            d = {'msLevel':msLevel,'scan.peakDetect:%s':peakDetect}
1565 >            d = {'msLevel':msLevel}
1566              # Optional ('scan.' and prefixformat spec. needed)
1567              d.update({
1568                  'scan.polarity:%s':polarity_val,
1569                  })
1570  
1571              scanindex = self.maptoscan[(f,i)]
1572 <            d.update({
1573 <                'plateID':self.metadata['SCAN'][scanindex]['plateID'],
1574 <                'spotID':self.metadata['SCAN'][scanindex]['spotID'],
1575 <                })
1576 <            d.update({'scanOrigin.parentID:%s': self.distinct_datafiles[f],
1572 >            if len(self.metadata['SCAN']) > 0:
1573 >                d.update({
1574 >                    'plateID':self.metadata['SCAN'][scanindex]['plateID'],
1575 >                    'spotID':self.metadata['SCAN'][scanindex]['spotID'],
1576 >                    })
1577 >            if retentionTime != None:
1578 >                d.update({'scan.retentionTime:PT%fS':retentionTime});
1579 >            d.update({'scanOrigin.parentFileID:%s': self.distinct_datafiles[f],
1580                        'scanOrigin.num:%d': i})
1581              if msLevel == 1:
1582                  yield (dataArr,d)
# Line 1466 | Line 1591
1591              prevfile = f
1592  
1593          self.deapp.Documents.Close()
1469
1594          self.remsettingsfile(prevfile)
1595 +        self.remsettingsfile(f)
1596              
1597      def getMsRunMetaData(self):
1598          self.open()
# Line 1476 | Line 1601
1601      def getFilenames(self):
1602          return [ t for t in self.distinct_datafiles.items() ]
1603  
1604 +    def msInstrumentID(self):
1605 +        return "1"
1606 +
1607      def msManufacturer(self):
1608          return "ABI / SCIEX"
1609  
# Line 1504 | Line 1632
1632          return False
1633  
1634      def lc(self):
1635 <        return False
1635 >        return len(self.metadata['PLATE']) == 0
1636  
1637      def maldi(self):
1638          return not self.lc()
# Line 1596 | Line 1724
1724                        help="Level(s) of spectra to apply peak detection to (comma separated). QStar,4700 only.")
1725      parser.add_option("-f", "--filter", type="string", dest="filter", default=None,\
1726                        help="Filter on mzxml scan meta-data: field.op.value[,field.op.value]. Default: No filter.")
1727 <    parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False,\
1728 <                      help="Debug. First 10 spectra only, and truncated peaks data element. Default: False.")
1727 >    parser.add_option("-V", "--version", type='string', dest="version", default="3.0",
1728 >                      help="XML version. mzXML only. Valid options '2.1','2.2','3.0'. Default: '3.0'.")
1729 >    parser.add_option("-z", "--compress_peaks", action="store_true", dest="compress_peaks", default=None,\
1730 >                      help="Compress mzXML peaks data using zlib. Default: False")
1731      parser.add_option("-Z", "--compress", type="string", dest="compress", default=None,\
1732                        help="Compress output file. Valid options 'gz'. Default: None.")
1733 +    parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False,\
1734 +                      help="Debug. First 10 spectra only, and truncated peaks data element. Default: False.")
1735      
1736      ( opts, args ) = parser.parse_args()
1737  
# Line 1650 | Line 1782
1782              sys.exit(1)
1783  
1784          if opts.xmlformat.lower() == 'mzxml':
1785 <            x = ToMzXML(r,o,opts.compress,filt)
1785 >            x = ToMzXML(r,o,opts.compress,filt,opts.compress_peaks,opts.version)
1786          elif opts.xmlformat.lower() == 'mzdata':
1787              x = ToMzData(r,o,opts.compress,filt)
1788 <        elif opts.output[-6:].lower() in ('.mzxml',):
1789 <            x = ToMzXML(r,opts.output,opts.compress,filt)
1790 <        elif opts.output[-7:].lower() in ('.mzdata',):
1788 >        elif re.search(r'\.mzxml(\.gz)?$',opts.output,re.IGNORECASE):
1789 >            x = ToMzXML(r,opts.output,opts.compress,filt,opts.compress_peaks,opts.version)
1790 >        elif re.search(r'\.mzdata(\.gz)?$',opts.output,re.IGNORECASE):
1791              x = ToMzData(r,opts.output,opts.compress,filt)
1792          else:
1793              parser.error("Bad xml format specification.")

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines