#!/usr/bin/env python
"""
.. py:currentmodule:: FileFormat.Specimen
.. moduleauthor:: Hendrix Demers <hendrix.demers@mail.mcgill.ca>
MCXRay specimen input file.
"""
# Script information for the file.
__author__ = "Hendrix Demers (hendrix.demers@mail.mcgill.ca)"
__version__ = ""
__date__ = ""
__copyright__ = "Copyright (c) 2012 Hendrix Demers"
__license__ = ""
# Subversion informations for the file.
__svnRevision__ = "$Revision$"
__svnDate__ = "$Date$"
__svnId__ = "$Id$"
# Standard library modules.
import copy
# Third party modules.
# Local modules.
import pymcxray.FileFormat.Region as Region
import pymcxray.FileFormat.Version as Version
# Project modules
# Globals and constants variables.
KEY_NAME = "Name"
KEY_NUMBER_REGIONS = "NumberRegions"
KEY_REGIONS = "Regions"
[docs]class Specimen(object):
def __init__(self):
self.version = copy.deepcopy(Version.CURRENT_VERSION)
self._keys = self._createKeys()
self._parameters = {}
self.clear()
def _createKeys(self):
keys = []
keys.append(KEY_NUMBER_REGIONS)
#keys.append(KEY_REGIONS)
return keys
[docs] def clear(self):
self.numberRegions = 0
self.regions = []
self._shortHeader = False
def _createExtractMethods(self):
extractMethods = {}
extractMethods[KEY_NUMBER_REGIONS] = int
return extractMethods
[docs] def read(self, filepath):
self.clear()
self.version.readFromFile(filepath)
if self.version == Version.BEFORE_VERSION:
self._readOldVersion(filepath)
else:
self._readWithVersion(filepath)
def _readWithVersion(self, filepath):
lines = open(filepath, 'r').readlines()
indexLine = 0
for line in lines:
indexLine += 1
line = line.strip()
key = KEY_NUMBER_REGIONS
if line.startswith(key):
items = line.split('=')
self.numberRegions = int(items[-1])
break
for _indexRegion in range(self.numberRegions):
while lines[indexLine].strip() == "":
indexLine += 1
region = Region.Region()
self.regions.append(region)
indexLine += region.extractFromLinesWithVersion(lines[indexLine:])
def _readOldVersion(self, filepath):
lines = open(filepath, 'r').readlines()
extractMethods = self._createExtractMethods()
indexLine = 0
while indexLine < len(lines):
line = lines[indexLine]
line = line.strip()
indexLine += 1
if not line.startswith("***") and len(line) != 0:
self.numberRegions = extractMethods[KEY_NUMBER_REGIONS](line)
for _indexRegion in range(self.numberRegions):
# Skip blank line.
indexLine += 1
region = Region.Region()
self.regions.append(region)
indexLine += region.extractFromLinesWithoutVersion(lines[indexLine:])
[docs] def write(self, filepath):
assert self.numberRegions == len(self.regions)
outputFile = open(filepath, 'w')
self._writeHeader(outputFile)
self.version.writeLine(outputFile)
key = KEY_NUMBER_REGIONS
value = self.numberRegions
line = "%s=%s\n" % (key, value)
outputFile.write(line)
outputFile.write("\n")
for region in self.regions:
lines = region.createLinesWithVersion()
for line in lines:
outputFile.write(line+"\n")
outputFile.write("\n")
def _writeHeader(self, outputFile):
if self._shortHeader:
headerLines = \
"""********************************************************************************
""".splitlines()
elif self.version == Version.BEFORE_VERSION:
headerLines = \
"""********************************************************************************
*** SPECIMEN
***
*** First Entry is:
*** number of region (integer)
***
*** then region by region:
*** number of elements in region
*** first element atomic number (integer) mass concentration (double)
*** ...
*** last element atomic number (integer) mass concentration (double)
*** user's elements mass density if any (double)
*** region volume type: BOX, SPHERE or CYLINDER
*** region extents (all doubles):
*** BOX: minX maxX minY maxY minZ maxZ
*** SPHERE: posX posY posZ radius
*** CYLINDER: posX posY posZ dirX dirY dirZ lenght radius
*** the position is the center of the base of the cylinder
***
********************************************************************************
""".splitlines()
else:
headerLines = \
"""********************************************************************************
*** SPECIMEN
***
*** First Entry is:
*** number of region (integer)
***
*** then region by region:
*** number of elements in region
*** first element atomic number (integer) mass concentration (double)
*** ...
*** last element atomic number (integer) mass concentration (double)
*** user's elements mass density if larger than 0.0 (double)
*** region volume type: BOX, SPHERE or CYLINDER
*** region extents (all doubles):
*** BOX: minX maxX minY maxY minZ maxZ
*** SPHERE: posX posY posZ radius
*** CYLINDER: posX posY posZ dirX dirY dirZ lenght radius
*** the position is the center of the base of the cylinder
***
********************************************************************************
""".splitlines()
for line in headerLines:
outputFile.write(line+'\n')
@property
def version(self):
return self._version
@version.setter
def version(self, version):
self._version = version
@property
def name(self):
return self._parameters[KEY_NAME]
@name.setter
def name(self, name):
self._parameters[KEY_NAME] = name
@property
def numberRegions(self):
return self._parameters[KEY_NUMBER_REGIONS]
@numberRegions.setter
def numberRegions(self, numberRegions):
self._parameters[KEY_NUMBER_REGIONS] = numberRegions
@property
def regions(self):
return self._parameters[KEY_REGIONS]
@regions.setter
def regions(self, regions):
self._parameters[KEY_REGIONS] = regions