예제 #1
0
파일: IcdSupport.py 프로젝트: nasa/gunns
    def initialize(self, id, atLeastOneActiveEntry, action, icdElement):

        ## Create an XmlParser.
        parser = XmlParser()

        ## Comment out if not ready.
        if 'true' != icdElement.get(
                "isReadyForIcd") or False == atLeastOneActiveEntry:
            self.mCommentChar = "#"

        ## Initialize job data.
        self.mAction = action
        self.mRate = parser.getChildText(icdElement, "rate", id)
        self.mSimObject = parser.getChildText(icdElement, "simObject", id)
        self.mSimVarName = parser.getChildText(icdElement, "simVarName",
                                               id).replace("%s", id)
예제 #2
0
    def __init__(self):
        uninitialized = "[not initialized]"

        ## An XmlParser() object for getting data from xml elements.
        self.mParser = XmlParser()
        ## An xml entry from a registry file. This object is only associated with a single entry.
        self.mEntry = uninitialized
        ## A dictionary with the definitions of symbols used in the registries
        self.mSymMap = uninitialized
        ## Name of the Thermal Gunns link, as read from the registry entry.
        self.mName = uninitialized
        ## The link's number in the network's array. Initialized to an invalid value of -1.
        self.mEnumIndex = -1
        ## The link's description
        self.mDescription = uninitialized
        ## Initialization flag.
        self.mIsInitialized = False
예제 #3
0
    def __init__(self):
        uninitialized = "[not initialized]"

        ## IcdSettings() object contains specifics used in Thermal Aspect ICD printing.
        ## For example, the IcdBuilder needs to know that:
        ## - On the registry, a capacitance link uses the XML tag <temperature> to describe
        ##    an ICD "READ" exchange.
        ## - The unit for temperature is "K".
        ## - The PTCS member that contains the temperature is
        ##    "therm.mCapacitanceLinks[%s].mTemperature".
        self.mIcdSettings = uninitialized

        ## Name of network using this IcdBuilder() class.
        self.mNetwork = uninitialized

        ## List of Icd Exchange() objects. This list is appended with all the WRITE/READ groups
        ## that are described in the thermal registry files. After all data has been read,
        ## the IcdBuilder loops through each and prints them to the PTCS.txt icd-file.
        self.mListOfExchanges = []

        ## An XmlParser() object for setting data in xml elements.
        self.mParser = XmlParser()
예제 #4
0
파일: SymbolLoading.py 프로젝트: nasa/gunns
    def __init__(self):
        ## An XmlParser() object for getting data from xml elements.
        self.mParser = XmlParser()

        ## Stores name of current file being parsed.
        self.mCurrentFile = "[mCurrentFile not set]"
예제 #5
0
파일: SymbolLoading.py 프로젝트: nasa/gunns
class SymbolLoader():
    ## @brief:
    ## Constructs the SymbolLoader and creates a XmlParser object.
    def __init__(self):
        ## An XmlParser() object for getting data from xml elements.
        self.mParser = XmlParser()

        ## Stores name of current file being parsed.
        self.mCurrentFile = "[mCurrentFile not set]"

    #===============================================================================================
    ## @brief:
    ## Main public function. Creates a dictionary based on symbols defined in the xml file.
    ## @param[in]: symFiles   name of xml-file containing symbols data
    ## @return:    a dictionary with key = symbol, value = resulting numerical value of symbol
    def execute(self, symFiles):

        masterNameList = []
        masterExpList = []

        for file in symFiles:
            ## Read each file.
            [nameList, expList, desList,
             groupList] = self.loadSymbolsFrom(file)

            ## Update master lists
            masterNameList = masterNameList + nameList
            masterExpList = masterExpList + expList

        return self.defineSymbols(masterNameList, masterExpList, locals())

    # ----------------------------------------------------------------------------------------------
    ## @brief:
    ## Private method. Defines a symbol list given an expression list.
    ## @param[in]: symFile       name of xml-file containing symbols data
    ## @param[in]: areDesAndGroupIncluded    a boolean to specify if the group/des tags need to be
    ##                                       read as well (like in the generate_TD_symbols case)
    ## @return:    nameList      list of text under <name> tag in symbols xml
    ## @return:    expList       list of text under <exp> tag in symbols xml
    def loadSymbolsFrom(self, symFile):

        ## Set current file for error reporting purposes.
        self.mCurrentFile = symFile

        ## Try to open the symbol file. Open it for reading and save its xml data.
        symbols = self.mParser.loadFile(symFile)

        ## Initialize lists.
        nameList = []
        expList = []
        desList = []
        groupList = []

        ## Loop over the symbols.
        for symbol in symbols:
            ## Initialize name for error reporting.
            name = "[error reading name]"

            ## Get data.
            try:
                name = self.mParser.getChildText(symbol, "name")
                expElem = self.mParser.getElements(symbol, "exp", True,
                                                   name)[0]
                expText = self.mParser.getText(expElem, name)

                if name in nameList:
                    ## If the symbol is a mass, it can overwrite a previous instance.
                    if 'mass_' == name[:5]:
                        expList[nameList.index(name)] = expText
                        continue
                    else:
                        raise ThermError("Symbol previously defined (%s)." %
                                         name)

                ## Special instructions for capacitance symbols, for mass accounting purposes.
                if 'cap_' == name[:4]:
                    try:
                        ## Read the given mass from the symbols element.
                        specHeatText = self.mParser.getChildText(
                            expElem, "specHeat", name)
                        massText = self.mParser.getChildText(
                            expElem, "mass",
                            name).replace('%Cp', specHeatText)
                        expText = "(%s) * (%s)" % (massText, specHeatText)

                    except (TagNotFound), e:
                        ## Store a "-1" as an indication that no mass data was provided.
                        massText = "-1"

                    ## Append a symbol for the mass.
                    nameList.append(name.replace("cap_", "mass_"))
                    expList.append(massText)

                ## Append name and expression to list.
                nameList.append(name)
                expList.append(expText)

            except (TagNotFound, ThermError), e:
                print e,
                print "Symbol will be ignored (%s)." % name
                continue
예제 #6
0
    def __init__(self):

        ## Initialization flag.
        self.mInitialized = False
        uninitialized = "[%s not initialized]"

        ## Name (abbreviation) of network to be built. Must be identical to string found
        ## in network-specific file names (e.g., 'trussMid' -> ThermNodes_trussMid.xml).
        self.mNetwork = uninitialized % "mNetwork"

        ## Name of top-level script that creates the ThermAspectBuilder that creates this object.
        self.mCallingScript = uninitialized % "mCallingScript"

        ## A dictionary with the definitions of symbols used in the registries
        self.mSymMap = uninitialized % "mSymMap"

        ## Assumption to use for any specific heat values (Cp) not provided directly.
        self.mAssumedCp = uninitialized % "mAssumedCp"

        ## An XmlParser() object for getting data from xml elements.
        self.mParser = XmlParser()
        ## A ThermPrinter() object for some printing utility functions.
        self.mPrinter = ThermPrinter()
        ## A dictionary used to maintain a record of Thermal Desktop nodes that were also
        ## included in the Thermal Aspect Registry.
        self.isRegistered = {}

        ## ICD builder object. Handles all ICD functionality.
        self.mIcdBuilder = IcdBuilder()

        #Files to read ............................................
        ## Path and file name of Thermal Aspect Registry file.
        self.mRegisFile = uninitialized % "mRegisFile"
        ## Path and file name of Thermal Desktop file (TdNetworkConfig).
        self.mTdFile = uninitialized % "mTdFile"
        ## Path and file name of HtrRegistry file.
        self.mHtrFile = uninitialized % "mHtrFile"
        ## Path and file name of ThermalPanel registry/config file.
        self.mPanFile = uninitialized % "mPanFile"

        #Files to generate ........................................
        ## Path and file name of Node configuration file.
        self.mNodeFile = uninitialized % "mNodeFile"
        ## Path and file name of Conduction configuration file.
        self.mCondFile = uninitialized % "mCondFile"
        ## Path and file name of Radiation configuration file.
        self.mRadFile = uninitialized % "mRadFile"
        ## Path and file name of Et.Cetera (potentials, sources) configuration file.
        self.mEtcFile = uninitialized % "mEtcFile"
        ## Path and file name of TrickView file. Each network produces its own TrickView file.
        self.mTvFile = uninitialized % "mTvFile"

        ## Initialize lists for enumerating.
        self.tdNodeList = []
        self.tdRadList = []
        self.regisNodeList = []
        self.masterNodeList = []
        self.mMassDict = {}
        self.mTempDict = {}
        self.mEditCapGroupList = []
        self.mPotList = []
        self.mSrcList = []
        self.mRadList = []
        self.mHtrList = []
        self.mPanList = []
        self.mCondNum = 0

        ## Boolean to determine if the mass of structural nodes should be adjusted to match a
        ## total-mass expected value.
        self.mIsMassAdjustable = uninitialized % "mIsMassAdjustable"
        ## Expected/Rated mass (kg) of the thermal network
        self.mExpectedMass = uninitialized % "mExpectedMass"
        ## Raw, unadjusted mass (kg) of the thermal network
        self.mUnadjustedMass = 0
        ## Scalar to multiply all structural node mass with the aim of matching the network's
        ## modeled mass to the rated mass.
        self.mStructMassScalar = 0

        ## Initialize new PTCS XML elements. These elements will be built up during the course of
        ## the network parsing/analysis. At the conclusion, when the xml trees are complete, they
        ## will be printed to generated thermal config-files.
        self.mNodeXml = self.mParser.newElement("list")
        self.mCondXml = self.mParser.newElement("list")
        self.mRadXml = self.mParser.newElement("list")
        self.mEtcXml = self.mParser.newElement("list")
예제 #7
0
class IndivNetworkBuilder():
    ## @brief:
    ## Default constructs the object with default, uninitialized members.
    def __init__(self):

        ## Initialization flag.
        self.mInitialized = False
        uninitialized = "[%s not initialized]"

        ## Name (abbreviation) of network to be built. Must be identical to string found
        ## in network-specific file names (e.g., 'trussMid' -> ThermNodes_trussMid.xml).
        self.mNetwork = uninitialized % "mNetwork"

        ## Name of top-level script that creates the ThermAspectBuilder that creates this object.
        self.mCallingScript = uninitialized % "mCallingScript"

        ## A dictionary with the definitions of symbols used in the registries
        self.mSymMap = uninitialized % "mSymMap"

        ## Assumption to use for any specific heat values (Cp) not provided directly.
        self.mAssumedCp = uninitialized % "mAssumedCp"

        ## An XmlParser() object for getting data from xml elements.
        self.mParser = XmlParser()
        ## A ThermPrinter() object for some printing utility functions.
        self.mPrinter = ThermPrinter()
        ## A dictionary used to maintain a record of Thermal Desktop nodes that were also
        ## included in the Thermal Aspect Registry.
        self.isRegistered = {}

        ## ICD builder object. Handles all ICD functionality.
        self.mIcdBuilder = IcdBuilder()

        #Files to read ............................................
        ## Path and file name of Thermal Aspect Registry file.
        self.mRegisFile = uninitialized % "mRegisFile"
        ## Path and file name of Thermal Desktop file (TdNetworkConfig).
        self.mTdFile = uninitialized % "mTdFile"
        ## Path and file name of HtrRegistry file.
        self.mHtrFile = uninitialized % "mHtrFile"
        ## Path and file name of ThermalPanel registry/config file.
        self.mPanFile = uninitialized % "mPanFile"

        #Files to generate ........................................
        ## Path and file name of Node configuration file.
        self.mNodeFile = uninitialized % "mNodeFile"
        ## Path and file name of Conduction configuration file.
        self.mCondFile = uninitialized % "mCondFile"
        ## Path and file name of Radiation configuration file.
        self.mRadFile = uninitialized % "mRadFile"
        ## Path and file name of Et.Cetera (potentials, sources) configuration file.
        self.mEtcFile = uninitialized % "mEtcFile"
        ## Path and file name of TrickView file. Each network produces its own TrickView file.
        self.mTvFile = uninitialized % "mTvFile"

        ## Initialize lists for enumerating.
        self.tdNodeList = []
        self.tdRadList = []
        self.regisNodeList = []
        self.masterNodeList = []
        self.mMassDict = {}
        self.mTempDict = {}
        self.mEditCapGroupList = []
        self.mPotList = []
        self.mSrcList = []
        self.mRadList = []
        self.mHtrList = []
        self.mPanList = []
        self.mCondNum = 0

        ## Boolean to determine if the mass of structural nodes should be adjusted to match a
        ## total-mass expected value.
        self.mIsMassAdjustable = uninitialized % "mIsMassAdjustable"
        ## Expected/Rated mass (kg) of the thermal network
        self.mExpectedMass = uninitialized % "mExpectedMass"
        ## Raw, unadjusted mass (kg) of the thermal network
        self.mUnadjustedMass = 0
        ## Scalar to multiply all structural node mass with the aim of matching the network's
        ## modeled mass to the rated mass.
        self.mStructMassScalar = 0

        ## Initialize new PTCS XML elements. These elements will be built up during the course of
        ## the network parsing/analysis. At the conclusion, when the xml trees are complete, they
        ## will be printed to generated thermal config-files.
        self.mNodeXml = self.mParser.newElement("list")
        self.mCondXml = self.mParser.newElement("list")
        self.mRadXml = self.mParser.newElement("list")
        self.mEtcXml = self.mParser.newElement("list")

    #===============================================================================================
    ## @brief:
    ## Public function, called by ThermAspectBuilder class. Initializes the object with its
    ## configuration data.
    ## @param[in]: config   IndivNetworkConfig object with its file names set explicitly by
    ##                      the top-level orchestrator.
    def initialize(self, config):

        ## Name (abbreviation) of network to be built. Must be identical to string found
        ## in network-specific file names (e.g., 'trussMid' -> ThermNodes_trussMid.xml).
        self.mNetwork = config.cNetwork

        ## Name of top-level script that creates the ThermAspectBuilder that creates this object.
        self.mCallingScript = config.cCallingScript

        ## A dictionary with the definitions of symbols used in the registries
        self.mSymMap = config.cSymMap

        ## Assumption to use for any specific heat values (Cp) not provided directly.
        self.mAssumedCp = config.cAssumedCp

        ## Boolean to determine if the mass of structural nodes should be adjusted to match a
        ## total-mass expected value.
        self.mIsMassAdjustable = config.cIsMassAdjustable

        ## Expected/Rated mass (kg) of the thermal network
        self.mExpectedMass = None

        ## Initialize file paths.
        self.mRegisFile = config.cRegisFile
        self.mTdFile = config.cTdFile
        self.mNodeFile = config.cNodeFile
        self.mCondFile = config.cCondFile
        self.mRadFile = config.cRadFile
        self.mPanFile = config.cPanFile
        self.mHtrFile = config.cHtrFile
        self.mEtcFile = config.cEtcFile
        self.mTvFile = config.cTvFile

        ## Initialize IcdBuilder object with basic ICD data.
        self.mIcdBuilder.initialize(self.mNetwork, config.cIcdSettings)

        ## Set initialization flag.
        self.mInitialized = True

    #===============================================================================================
    ## @brief:
    ## Public function, called by ThermAspectBuilder class. Reads Thermal Desktop data in
    ## TdNetworkConfig file. Reads user-generated data in Thermal Aspect Registry, Heater Registry,
    ## and ThermalPanel config file. Prints node, conduction, radiation, and potential data to
    ## xml files used directly in the sim.
    def execute(self):

        if False == self.mInitialized:
            raise ThermError("IndivNetworkBuilder (%s) not initialized." %
                             self.mNetwork)

        try:
            ## Read the TdNetworkConfig file.
            tdData = self.readThermalDesktopData()

            ## Parse and analyze ThermRegistry.
            self.readThermRegistry()

            ## Perform Mass Analysis.
            self.performMassAnalysis()

            ## Append ThermalDesktop data to the end of the xml config-files.
            self.appendThermalDesktopData(tdData)

            ## Heaters and panels are both derived from GunnsThermalSource, and they both have very
            ## similar registry schemas. They can be parsed with the same function.
            self.readThermSourceFile("heater", self.mHtrFile, self.mHtrList)
            self.readThermSourceFile("panel", self.mPanFile, self.mPanList)
            self.readThermSourceFile("source", self.mHtrFile, self.mSrcList)

            ## Write XML trees to file.
            self.mPrinter.printThermXml(self.mNodeXml, self.mNodeFile,
                                        self.mCallingScript)
            self.mPrinter.printThermXml(self.mCondXml, self.mCondFile,
                                        self.mCallingScript)
            self.mPrinter.printThermXml(self.mRadXml, self.mRadFile,
                                        self.mCallingScript)
            self.mPrinter.printThermXml(self.mEtcXml, self.mEtcFile,
                                        self.mCallingScript)

        except ThermError, e:
            print e,
            raise ThermError("Error executing network (%s)." % self.mNetwork)
예제 #8
0
 def test_51_execution(self):
     print "\n(5.1) Test execution.\n  ",
     
     capExplicit = "0"
     radEntries = None
     radCoeffRegis = ""
     radCoeffTd = ""
     try:
         self.article.execute()
         
         ## Check mass calculation
         parser = XmlParser()
         data = parser.loadFile(tNodePath % tNetwork)
         ## Open it for reading and save its xml data.
         entries = parser.getElements(data, "node")
 
         ## Loop through each source entry, totaling the mass.
         massSum = 0;
         for entry in entries:                
             ## Create and initialize XmlEntryAnalyzer object.
             mass = parser.getChildText(entry, "mass")
             massSum = massSum + float(mass)
             
             ## Store capacitance of a specific node in question.
             if "GOOD_EXPLICIT_12" == parser.getChildText(entry, "name"):
                 capExplicit = parser.getChildText(entry, "capacitance") 
         
         ## Read radiation data for testing.    
         radData = parser.loadFile(tRadPath % tNetwork)
         radEntries = parser.getElements(radData, "radiation")
         ## Check radiation coefficients.  
         radCoeffTd = parser.getChildText(radEntries[0], "coefficient")
         radCoeffRegis = parser.getChildText(radEntries[1], "coefficient")
                     
     except (Exception), e:
         print e
         self.fail("Uncaught exception during execute().")
예제 #9
0
class XmlEntryAnalyzer:
    ## @brief:
    ## Default constructs the object with default, uninitialized members.
    def __init__(self):
        uninitialized = "[not initialized]"

        ## An XmlParser() object for getting data from xml elements.
        self.mParser = XmlParser()
        ## An xml entry from a registry file. This object is only associated with a single entry.
        self.mEntry = uninitialized
        ## A dictionary with the definitions of symbols used in the registries
        self.mSymMap = uninitialized
        ## Name of the Thermal Gunns link, as read from the registry entry.
        self.mName = uninitialized
        ## The link's number in the network's array. Initialized to an invalid value of -1.
        self.mEnumIndex = -1
        ## The link's description
        self.mDescription = uninitialized
        ## Initialization flag.
        self.mIsInitialized = False

    #===============================================================================================
    ## @brief:
    ## Constructs the class using two arguments.
    ## @param[in]: entry    ElementTree xml-element of data from Thermal, Htr, or Panel registry
    ## @param[in]: symMap   dictionary with the definitions of symbols used in the registries
    def initialize(self, entry, symMap={}):

        ## An xml entry from a registry file. This object is only associated with a single entry.
        self.mEntry = entry
        ## A dictionary with the definitions of symbols used in the registries
        self.mSymMap = symMap
        ## Name of the Thermal Gunns node/link, as read from the registry entry.
        self.mName = entry.get("name")

        ## The node entry must have a name. Raise exception if otherwise.
        if None == self.mName:
            raise ThermError("Must have a name attribute.")

        ## The link's description as read from registry entry.
        try:
            self.mDescription = self.mParser.getChildText(entry, "des")
        except TagNotFound:
            self.mDescription = ""

    #===============================================================================================
    ## @brief:
    ## Evaluate an expression value based on symbols defined in mSymMap.
    ## @param[in]: expr    a mathematical expression that may contain symbols defined in mSymMap
    ## @param[in]: info    optional string used in error reporting
    ## @return:    the evaluated expression in numerical form
    def getValidatedValue(self, expr, info=''):
        try:
            value = eval(expr, globals(), self.mSymMap)
        except (NameError, SyntaxError), e:
            print e,
            raise ThermError("Invalid value: %s (%s)." % (expr, info))

        ## Do not accept negative values.
        if value < 0:
            raise ThermError("Cannot accept a negative. %s = %f" %
                             (expr, value))

        return value
예제 #10
0
class IcdBuilder:
    ## @brief:
    ## Default constructs the object with default, uninitialized members.
    def __init__(self):
        uninitialized = "[not initialized]"

        ## IcdSettings() object contains specifics used in Thermal Aspect ICD printing.
        ## For example, the IcdBuilder needs to know that:
        ## - On the registry, a capacitance link uses the XML tag <temperature> to describe
        ##    an ICD "READ" exchange.
        ## - The unit for temperature is "K".
        ## - The PTCS member that contains the temperature is
        ##    "therm.mCapacitanceLinks[%s].mTemperature".
        self.mIcdSettings = uninitialized

        ## Name of network using this IcdBuilder() class.
        self.mNetwork = uninitialized

        ## List of Icd Exchange() objects. This list is appended with all the WRITE/READ groups
        ## that are described in the thermal registry files. After all data has been read,
        ## the IcdBuilder loops through each and prints them to the PTCS.txt icd-file.
        self.mListOfExchanges = []

        ## An XmlParser() object for setting data in xml elements.
        self.mParser = XmlParser()

    #===============================================================================================
    ## @brief:
    ## Public function. Initializes the class with data common to all icd actions.
    ## @param[in]: network      string of abbreviated network name, as found in Thermal file names
    ##                                                ex: 'trussMid' -> ThermNodes_trussMid.xml
    ## @param[in]: icdSettings  IcdSettings() obj containing specifics used in Thermal ICD printing
    def initialize(self, network, icdSettings):

        ## Network this IcdBuilder was made for.
        self.mNetwork = network

        ## ICD settings specific to this network
        self.mIcdSettings = icdSettings

    #===============================================================================================
    ## @brief:
    ## Public function, called by IndivNetworkBuilder. This function reads the data in a
    ## ThermRegistryEntryAnalyzer object and from it, creates and initializes IcdExchange objects.
    ## @param[in]: entryObj      An initialized ThermRegistryEntryAnalyzer object
    ## @param[in]: linkType      type of Gunns object, either "potential" or "capacitance"
    ## @param[in]: enumIndex     the number in the PTCS enumeration (its array index in the
    ##                               Gunns thermal link array)
    def extractAndProcessIcd(self, entryObj, linkType, enumIndex):

        ## Get link type, id, and description.
        comments = entryObj.mDescription
        identifier = entryObj.mName
        if "potential" == linkType:
            identifier = "pot_" + identifier

        ## Get icd data contained in entryObj.
        linkElements = self.mParser.getElements(entryObj.mEntry, linkType)
        if len(linkElements) != 1:
            return

        ## Process Icd.
        self.processIcd(linkElements[0], identifier, linkType, enumIndex,
                        comments)

    #===============================================================================================
    ## @brief:
    ## Public function, called by IndivNetworkBuilder. This function reads the data in a
    ## ThermRegistryEntryAnalyzer object and from it, creates and initializes IcdExchange objects.
    ## @param[in]: element       xml-element containing an icd job, whose tag depends on linkType
    ## @param[in]: identifier    string that identifies the particular link, used
    ##                               in the PTCS enumeration
    ## @param[in]: linkType      type of Gunns object, either "potential" or "capacitance"
    ## @param[in]: enumIndex     the number in the PTCS enumeration (its array index in the
    ##                               Gunns thermal link array)
    ## @param[in]: comments      comments describing icd exchange
    def processIcd(self, element, identifier, linkType, enumIndex, comments):

        ## Declare generic data.
        pui = "xxxx"
        subsys = "ptcs"
        type = "double"

        try:
            ## Find the icd category, the tag name under which the icd data is contained
            ## (<temperature>, <heatFlux>, <viewScalar>, etc).
            categoryThatPtcsReads = self.mIcdSettings.mCategoryThatPtcsReads[
                linkType]
            categoryThatPtcsWrites = self.mIcdSettings.mCategoryThatPtcsWrites[
                linkType]

            ## Get icd data.
            otherSubsWrites = self.mParser.getElements(element,
                                                       categoryThatPtcsReads)
            otherSubsReads = self.mParser.getElements(element,
                                                      categoryThatPtcsWrites)

            #.............................
            ## PTCS Writing
            if len(otherSubsReads) > 0:
                ## Create an IcdExchange object and append it to mListOfExchanges.
                self.createIcdExchange(identifier, linkType, enumIndex, categoryThatPtcsWrites, "",\
                                       None, otherSubsReads, pui, subsys, type, comments)
            #.............................
            ## PTCS Reading
            for i in range(0, len(otherSubsWrites)):
                ## Create an IcdExchange object and append it to mListOfExchanges.
                self.createIcdExchange(identifier, linkType, enumIndex, categoryThatPtcsReads, str(i),\
                                       otherSubsWrites[i], None, pui, subsys, type, comments)

        except (ThermError, TagNotFound), e:
            print e,
            print "%s job will not be written on ICD." % identifier