Esempio n. 1
0
def uniqueResponses(staxml):
    uniqResponse = []
    for n in staxml.Network:
      for s in n.Station:
        for c in s.Channel:
          chanCode = checkNRL.getChanCodeId(n, s, c)
          foundMatch = None
          if VERBOSE: print "chanCode %s "%(chanCode, )
#          print "chanCode %s numStage = %d"%(chanCode, len(c.Response.Stage),)
          for uResp in uniqResponse:
#              try:
              result = areSameResponse(c.Response, uResp[1])
#              except:
#                e =  sys.exc_info()[0]
#                print "Error comparing %s, %s"%(uResp[0], e)
#                result = False, " %s"%(e,)
#                return
              if VERBOSE: print "areSame %s: %s"%(result[0], result[1],)
              if result[0]:
                  foundMatch = uResp
                  break
          if foundMatch is None:
              uniqResponse.append( ( chanCode, c.Response, [ chanCode] ) ) 
              if VERBOSE: print "no match %d"%(len(uniqResponse),)
          else:
              foundMatch[2].append(chanCode)
              if VERBOSE: print "found match %s  %s"%(chanCode, foundMatch[0])
    return uniqResponse
Esempio n. 2
0
def main():
    checkNRL.setVerbose(True)
    args = sys.argv[1:]
    if len(args) == 0:
        usage()
        return
    if not os.path.isfile(args[0]):
        print "Can't find file %s"%(args[0],)
        return
    staxml = sisxmlparser.parse(args[0])
    if args[1] == '--list':
      print "--all channels--"
      for n in staxml.Network:
        for s in n.Station:
          for c in s.Channel:
            cCode = checkNRL.getChanCodeId(n,s,c)
            print cCode
      return

    chanA = None
    chanB = None
    for n in staxml.Network:
      for s in n.Station:
        for c in s.Channel:
          cCode = checkNRL.getChanCodeId(n,s,c)
          if cCode == args[1]:
              chanA = c
          if cCode == args[2]:
              chanB = c
    if chanA is None or chanB is None:
        print "did not find channels: %s %s %s %s"%(chanA, chanB, args[1], args[2])
        return

    print "Sensor compare: %s"%(uniqResponses.areSameStageByIndex(chanA.Response, chanB.Response, 1),)
    result = uniqResponses.areSameResponse(chanA.Response, chanB.Response)
    print result
Esempio n. 3
0
def fixResponseNRL(n, s, c, uniqResponse, namespace):

  chanCodeId = checkNRL.getChanCodeId(n, s, c)

  if VERBOSE:
      print "fixResponseNRL: %s"%(chanCodeId,)
  if c.Response is None:
     print "Channel has no Response: "+chanCodeId
     return

  oldResponse = c.Response
  c.Response = sisxmlparser.SISResponseType()
  if oldResponse.InstrumentSensitivity != None:
      c.Response.InstrumentSensitivity = oldResponse.InstrumentSensitivity
  else:
      # need to calculate overall sensitivity
      print "WARNING: %s does not have InstrumentSensitivity, this is required in SIS."%(chanCodeId,)

  if hasattr(c, 'Sensor'):
      #sometimes equipment comment in Sensor.Type
      if hasattr(c.Sensor, 'Type'):
          if not hasattr(c, 'Comment'):
              c.Comment = []
          comment = sisxmlparser.CommentType()
          comment.Value = "Sensor.Type: "+c.Sensor.Type
          c.Comment.append(comment)
      del c.Sensor
  if not hasattr(oldResponse, 'Stage'):
      print "WARNING: %s's Response does not have any Stage elements."%(chanCodeId,)
      return

  sensorSubResponse = sisxmlparser.SubResponseType()
  sensorSubResponse.sequenceNumber = 1
  preampSubResponse = sisxmlparser.SubResponseType()
  preampSubResponse.sequenceNumber = 2
  atodSubResponse = sisxmlparser.SubResponseType()
  atodSubResponse.sequenceNumber = 3
  loggerSubResponse = sisxmlparser.SubResponseType()
  loggerSubResponse.sequenceNumber = 4
  for prototypeChan, namedResponse, chanCodeList, sss, lll in uniqResponse:
      for xcode in chanCodeList:
          if xcode == chanCodeId:
              # sensor ######
              if len(sss) == 0 :
                  if VERBOSE: print " sensor not NRL, use named resp: %s"%(xcode,)
                  # not nrl, so use named response
                  sensorSubResponse.ResponseDictLink = sisxmlparser.ResponseDictLinkType2()
                  sensorSubResponse.ResponseDictLink.Name = "S_"+prototypeChan
                  sensorSubResponse.ResponseDictLink.SISNamespace = namespace
                  sensorSubResponse.ResponseDictLink.Type = 'PolesZeros'
                  sensorSubResponse.ResponseDictLink.Gain = sisxmlparser.SISGainType()
                  sensorSubResponse.ResponseDictLink.Gain.Value = oldResponse.Stage[0].StageGain.Value
                  sensorSubResponse.ResponseDictLink.Gain.Frequency = oldResponse.Stage[0].StageGain.Frequency
                  sensorSubResponse.ResponseDictLink.Gain.InputUnits = oldResponse.Stage[0].PolesZeros.InputUnits
                  sensorSubResponse.ResponseDictLink.Gain.OutputUnits = oldResponse.Stage[0].PolesZeros.OutputUnits

              else:
                  if len(sss) > 1:
                    print "WARNING: %s has more than one matching sensor response in NRL, using first"%(chanCodeId,)
                    for temps in sss:
                      print "  %s"%(temps[0],)
                  if VERBOSE: print " sensor in NRL: %s"%(xcode,)
                  sensorSubResponse.RESPFile = sisxmlparser.RESPFileType()
                  sensorSubResponse.RESPFile.ValueOf = sss[0][0].replace("nrl", NRL_PREFIX)
                  # stage To/From not required for NRL responses, use SIS rules
                  #sensorSubResponse.RESPFile.stageFrom = 1
                  #sensorSubResponse.RESPFile.stageTo = 1
              # datalogger #######
              if len(lll) == 0:
                  if VERBOSE: print " logger not NRL, use named resp: %s"%(xcode,)
                  # not nrl, so use named response
                  if isOnlyGainStage(namedResponse, 2):
                      preampSubResponse.PreampGain = namedResponse.Stage[1].StageGain.Value
                  else:
                      preampSubResponse = None
                      atodSubResponse.sequenceNumber = 2
                      loggerSubResponse.sequenceNumber = 3
                  if not isAtoDStage(namedResponse, atodSubResponse.sequenceNumber):
                      raise Exception('Expected AtoD stage as %d, but does not look like V to COUNT Cefficients: %s'%(loggerSubResponse.sequenceNumber, chanCodeId))
                  atodSubResponse.ResponseDetail = sisxmlparser.SubResponseDetailType()
                  atodSubResponse.ResponseDetail.Gain = sisxmlparser.SISGainType()
                  atodOld = namedResponse.Stage[atodSubResponse.sequenceNumber-1]
                  atodSubResponse.ResponseDetail.Gain.Value = atodOld.StageGain.Value
                  atodSubResponse.ResponseDetail.Gain.Frequency = atodOld.StageGain.Frequency
                  atodSubResponse.ResponseDetail.Gain.InputUnits = atodOld.Coefficients.InputUnits
                  atodSubResponse.ResponseDetail.Gain.OutputUnits = atodOld.Coefficients.OutputUnits
                  # check make sure there are more stages
                  if len(namedResponse.Stage) < loggerSubResponse.sequenceNumber:
                      loggerSubResponse = None
                  else:
                      loggerSubResponse.ResponseDictLink = sisxmlparser.ResponseDictLinkType()
                      loggerSubResponse.ResponseDictLink.Name = "L_"+prototypeChan
                      loggerSubResponse.ResponseDictLink.SISNamespace = namespace
                      loggerSubResponse.ResponseDictLink.Type = 'FilterSequence'
              else:
                  if len(lll) > 1:
                    print "WARNING: %s has more than one matching logger response in NRL, using first"%(chanCodeId,)
                    for templ in lll:
                      print "  %s"%(templ[0],)
                  if VERBOSE: print " logger in NRL: %s"%(xcode,)
                  loggerSubResponse.RESPFile = sisxmlparser.RESPFileType()
                  loggerSubResponse.RESPFile.ValueOf = lll[0][0].replace("nrl", NRL_PREFIX)
                  # stage To/From not required for NRL responses, use SIS rules
                  #loggerSubResponse.RESPFile.stageFrom = lll[0][2]
                  #loggerSubResponse.RESPFile.stageTo = lll[0][3]
               
  c.Response.SubResponse = []
  c.Response.SubResponse.append( sensorSubResponse)
  if preampSubResponse != None:
      c.Response.SubResponse.append(preampSubResponse)
  if atodSubResponse != None:
      # might be None in case of NRL logger
      c.Response.SubResponse.append(atodSubResponse)
  if loggerSubResponse is not None:
      c.Response.SubResponse.append( loggerSubResponse )
Esempio n. 4
0
def main():
    sisNamespace = "TESTING"
    parseArgs = initArgParser()
    if parseArgs.verbose:
        VERBOSE=True
    sisNamespace = parseArgs.namespace
    if parseArgs.stationxml:

        if not os.path.exists(parseArgs.stationxml):
            print "ERROR: can't fine stationxml file %s"%(parseArgs.stationxml,)
            return

        # validate with SIS validator
        # http://maui.gps.caltech.edu/SIStrac/wiki/SIS/Code

       
        if os.path.exists('xerces-2_11_0-xml-schema-1.1-beta') and os.path.exists('validator/ValidateStationXml.class'):
            print "Validating xml..."
            try:
                validateOut = subprocess.check_output(['java', '-cp', 'validator:xerces-2_11_0-xml-schema-1.1-beta/xercesImpl.jar:xerces-2_11_0-xml-schema-1.1-beta/xml-apis.jar:xerces-2_11_0-xml-schema-1.1-beta/serializer.jar:xerces-2_11_0-xml-schema-1.1-beta/org.eclipse.wst.xml.xpath2.processor_1.1.0.jar:.', 'ValidateStationXml', '-i', parseArgs.stationxml])
            except subprocess.CalledProcessError as e:
                validateOut = "error calling process: " + e.output
            validateOut = validateOut.strip()
            if not validateOut == '0':
                print "ERROR: invalid stationxml document, errors: '%s'"%(validateOut,)
                return
            else:
                print "OK"
        else:
            print """
ERROR: Can't find validator: %s %s
            
            wget http://mirror.cc.columbia.edu/pub/software/apache//xerces/j/binaries/Xerces-J-bin.2.11.0-xml-schema-1.1-beta.tar.gz
            tar zxf Xerces-J-bin.2.11.0-xml-schema-1.1-beta.tar.gz
            wget http://maui.gps.caltech.edu/SIStrac/raw-attachment/wiki/SIS/Code/validator.tar.gz
            tar ztf validator.tar.gz

We assume the directories validator and xerces-2_11_0-xml-schema-1.1-beta
are in current directory for validation.
            """%(os.path.exists('xerces-2_11_0-xml-schema-1.1-beta') , os.path.exists('validator/ValidateStationXml.class'))
          
            return

        # Parse an xml file
        rootobj = sisxmlparser.parse(parseArgs.stationxml)
        origModuleURI = rootobj.ModuleURI

        rootobj.schemaVersion='1.0',
        rootobj.Source=parseArgs.namespace
        rootobj.Sender=parseArgs.namespace
        rootobj.Module='sta2extsta.py',
        rootobj.ModuleURI='https://github.com/crotwell/2extStationXML',
        rootobj.Created=datetime.datetime.now()

        if not hasattr(rootobj, 'comments'):
            rootobj.comments = []
        rootobj.comments.append("From: "+origModuleURI)

        # del non-matching channels
        if parseArgs.onlychan:
            pattern = re.compile(parseArgs.onlychan)
            for n in rootobj.Network:
                for s in n.Station:
                    tempChan = []
                    for c in s.Channel:
                        locid = c.locationCode
                        if locid is None or len(locid) == 0:
                            locid = "--"
                        if pattern.match(c.code):
                            tempChan.append(c)
                        elif pattern.match("%s.%s"%(locid, c.code)):
                            tempChan.append(c)
                        else:
                            if VERBOSE:
                                print "Skip %s as doesn't match --onlychan"%(checkNRL.getChanCodeId(n, s, c),)
                    s.Channel = tempChan
                  
        for n in rootobj.Network:
            for s in n.Station:
                tempChan = []
                for c in s.Channel:
                    if hasattr(c, 'Response') and hasattr(c.Response, 'Stage') and isOnlyGainStage(c.Response, 1):
                         # for weird case of gain channels for gain-ranged channels
                         # input and output units should be volts and we will
                         # insert a fake unity sensor for this.
                         if c.Response.InstrumentSensitivity.InputUnits.Name == 'V' and c.Response.Stage[1].Coefficients.InputUnits.Name == 'V':
                             print "INFO: adding unity V to V polezero to stage 1 for %s.%s.%s.%s"%(n.code, s.code, c.locationCode, c.code)
                             pzTemp = sisxmlparser.PolesZerosType()
                             pzTemp.InputUnits = c.Response.InstrumentSensitivity.InputUnits
                             pzTemp.OutputUnits = c.Response.Stage[1].Coefficients.InputUnits
                             pzTemp.PzTransferFunctionType = "LAPLACE (RADIANS/SECOND)"
                             pzTemp.NormalizationFactor = 1
                             pzTemp.NormalizationFrequency = 1
                             pzTemp.Zero = []
                             pzTemp.Pole = []
                             c.Response.Stage[0].PolesZeros = pzTemp
                         else:
                             print "WARNING: can't fix stage 1, no poleszeros for %s.%s.%s.%s"%(n.code, s.code, c.locationCode, c.code)
 
                                 

# Cannot use 'xsi:type' as an identifier which is how it is 
# stored in the object. So a set function has been defined for this 
# one case. Use it only when the type has been extended - RootType, 
# StationType, ChannelType, GainType, and ResponseType
        rootobj.settype('sis:RootType')

        if not os.path.exists(parseArgs.nrl):
            print "ERROR: can't find nrl dir at '%s', get with 'svn checkout http://seiscode.iris.washington.edu/svn/nrl/trunk nrl"%(parseArgs.nrl,)
            return
        spsIndex = os.path.join(parseArgs.nrl, "logger_sample_rate.sort")
        if not os.path.exists(spsIndex):
            print "ERROR: can't fine sps index file for NRL. Should be logger_sample_rate.sort inside NRL directory"
            print "python checkNRL.py --samplerate --nrl <path_to_nrl>"
            return

# load logger response by sample rate index file, speeds search
        if VERBOSE: print "load NRL sample rate index"
        loggerRateIndex = checkNRL.loadRespfileSampleRate(spsIndex)
# find all unique responses so only check identical channels once
        if VERBOSE: print "find unique responses in xml"
        uniqResponse = uniqResponses.uniqueResponses(rootobj)
# for each unique response, see if it is in the NRL so we use NRL instead of
# a in file named response
        if VERBOSE: print "look for responses in NRL...this could take a while"
        uniqWithNRL = checkNRL.checkRespListInNRL(parseArgs.nrl, uniqResponse, loggerRateIndex=loggerRateIndex)
        

        for n in rootobj.Network:
          print "%s "%(n.code,)
          for s in n.Station:
            print "    %s   "%(s.code, )
            if not hasattr(s, 'Operator'):
                s.Operator = []
                sOp = sisxmlparser.OperatorType()
                sOp.Agency = []
                sOp.Agency.append(parseArgs.operator)
                s.Operator.append(sOp)
            allChanCodes = {}
            tempChan = []
            for c in s.Channel:
              if c.endDate > datetime.datetime.now() and parseArgs.delcurrent:
                 print "        %s.%s --delcurrent: delete channel ends after now %s "%(c.locationCode, c.code, checkNRL.getChanCodeId(n,s,c),)
              else:
                 tempChan.append(c)
            s.Channel = tempChan

            for c in s.Channel:
                print "        %s.%s "%(c.locationCode, c.code,)
                key = "%s.%s"%(c.locationCode, c.code)
                if not key in allChanCodes:
                    allChanCodes[key] = []
                allChanCodes[key].append(c)
                fixResponseNRL(n, s, c, uniqWithNRL, sisNamespace)

            for key, epochList in allChanCodes.iteritems():
              epochList.sort(key=getStartDate)
            

        
        # save old stage as named and added so only add each unique stage once
        # this is only for logger stages as sensor is taken care of in fixResponseNRL
        prevAddedFilterStage = {}

        respGroup = sisxmlparser.ResponseDictGroupType()
        respGroup.ResponseDict = []
        for prototypeChan, namedResponse, chanCodeList, sss, lll in uniqWithNRL:
            if not hasattr(namedResponse, 'Stage'):
                # no stages, so do not need to add
                continue
            if VERBOSE: print "add to hardware, prototype: "+prototypeChan
            if len(sss) == 0:
                # add stage 1 as sensor
                sensor = sisxmlparser.ResponseDictType()
                if hasattr(namedResponse.Stage[0], "PolesZeros"):
                    sensor.PolesZeros = toSISPolesZeros(namedResponse.Stage[0].PolesZeros)
                    sensor.PolesZeros.name = "S_"+prototypeChan
                    sensor.PolesZeros.SISNamespace = sisNamespace 
                else:
                    print "WARNING: sensor response for %s doesnot have PolesZeros"%(prototypeChan,)
                    return
                respGroup.ResponseDict.append(sensor)
                    
            if len(lll) == 0:
                # add later stages as logger
                logger = sisxmlparser.ResponseDictType()
                logger.FilterSequence = sisxmlparser.FilterSequenceType()
                logger.FilterSequence.name = "L_"+prototypeChan
                logger.FilterSequence.SISNamespace = sisNamespace 
                logger.FilterSequence.FilterStage = []
                loggerStartStage = 2
                if isOnlyGainStage(namedResponse, 2):
                    #stage 2 is gain only, so assume preamp "
                    loggerStartStage = 3
                # array index is 0-base, stage number is 1-base, so -1
                # first logger stage should be AtoD stage and SIS wants
                # that separate from the filter chain
                if not hasattr(namedResponse.Stage[loggerStartStage-1], "Coefficients"):
                   print "ERROR: expecting AtoD stage, which should have Coefficients, but not found. %d %s"%(loggerStartStage, prototypeChan)
                   return
                if not (namedResponse.Stage[loggerStartStage-1].Coefficients.InputUnits.Name == 'V' and namedResponse.Stage[loggerStartStage-1].Coefficients.OutputUnits.Name == 'COUNTS'):
                   # no AtoD???, quit with error
                   print "ERROR: Was expecting AtoD stage, V to COUNTS, but found %s to %s, %s"%(namedResponse.Stage[loggerStartStage-1].Coefficients.InputUnits.Name, namedResponse.Stage[loggerStartStage-1].Coefficients.OutputUnits.Name, prototypeChan)
                   return
                # now deal with actual filter chain
                for s in namedResponse.Stage[loggerStartStage : ]:
                   # first search to see if we have already added this filter stage
                   found = False
                   for oldName, oldStage in prevAddedFilterStage.iteritems():
                       if uniqResponses.areSameStage(s, oldStage)[0]:
                           found=True
                           break
                   filterStage = sisxmlparser.FilterStageType()
                   filterStage.SequenceNumber = s.number
                   if hasattr(s, "Decimation"):
                       filterStage.Decimation = s.Decimation
                   else:
                       print "No decimation in %s stage %d but it is required"%(prototypeChan, s.number)
                   if hasattr(s, "StageGain"):
                       filterStage.Gain = s.StageGain
                   filterStage.Filter = sisxmlparser.FilterIDType()

                   if not found:
                       filterStage.Filter.Name = "FS_%d_%s"%(s.number, prototypeChan)
                       rd = createResponseDict(prototypeChan, s, sisNamespace)
                       respGroup.ResponseDict.append(rd)
                       prevAddedFilterStage[filterStage.Filter.Name] = s
                   else:
                       filterStage.Filter.Name = oldName
                   filterStage.Filter.SISNamespace = sisNamespace
                   # set type
                   if hasattr(s, "PolesZeros"):
                       filterStage.Filter.Type = "PolesZeros"
                   elif hasattr(s, "FIR"):
                       filterStage.Filter.Type = "FIR"
                   elif hasattr(s, "Coefficients"):
                       filterStage.Filter.Type = "Coefficients"
                   else:
                       print "stage does not have PZ, FIR or Coef: %s stage %s   \n%s"%(prototypeChan, s.number, dir(s))

                   logger.FilterSequence.FilterStage.append(filterStage)
                if len(namedResponse.Stage[loggerStartStage : ]) > 0:
                   # only add if not empty
                   respGroup.ResponseDict.append(logger)
                  

# add named non-NRL responses to HardwareResponse but not if respGroup is empty
        if len(respGroup.ResponseDict) > 0:
            if not hasattr(rootobj, "HardwareResponse"):
                rootobj.HardwareResponse = sisxmlparser.HardwareResponseType()
            if not hasattr(rootobj.HardwareResponse, "ResponseDictGroup"):
                rootobj.HardwareResponse.ResponseDictGroup = respGroup
            else:
                raise SISError ("rootobj already has HardwareResponse.ResponseDictGroup!")
# Finally after the instance is built export it. 
        rootobj.exportxml(parseArgs.outfile, 'FDSNStationXML', 'fsx', 0)