#!/bin/env python
# $Id: Data.py 3608 2015-10-27 11:18:36Z bnv $
#
# Copyright and User License
# ~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright Vasilis.Vlachoudis@cern.ch for the
# European Organization for Nuclear Research (CERN)
#
# All rights not expressly granted under this license are reserved.
#
# Installation, use, reproduction, display of the
# software ("flair"), in source and binary forms, are
# permitted free of charge on a non-exclusive basis for
# internal scientific, non-commercial and non-weapon-related
# use by non-profit organizations only.
#
# For commercial use of the software, please contact the main
# author Vasilis.Vlachoudis@cern.ch for further information.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the
# distribution.
#
# DISCLAIMER
# ~~~~~~~~~~
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY, OF
# SATISFACTORY QUALITY, AND FITNESS FOR A PARTICULAR PURPOSE
# OR USE ARE DISCLAIMED. THE COPYRIGHT HOLDERS AND THE
# AUTHORS MAKE NO REPRESENTATION THAT THE SOFTWARE AND
# MODIFICATIONS THEREOF, WILL NOT INFRINGE ANY PATENT,
# COPYRIGHT, TRADE SECRET OR OTHER PROPRIETARY RIGHT.
#
# LIMITATION OF LIABILITY
# ~~~~~~~~~~~~~~~~~~~~~~~
# THE COPYRIGHT HOLDERS AND THE AUTHORS SHALL HAVE NO
# LIABILITY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
# CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES OF ANY
# CHARACTER INCLUDING, WITHOUT LIMITATION, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA OR PROFITS,
# OR BUSINESS INTERRUPTION, HOWEVER CAUSED AND ON ANY THEORY
# OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCT
# LIABILITY OR OTHERWISE, ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGES.
#
# Author: Vasilis.Vlachoudis@cern.ch
# Date: 24-Oct-2006
import re
import math
import struct
import pymchelper.flair.common.fortran as fortran
import pymchelper.flair.common.bmath as bmath
from pymchelper.flair.common.log import say
__author__ = "Vasilis Vlachoudis"
__email__ = "Vasilis.Vlachoudis@cern.ch"
_detectorPattern = re.compile(r"^ ?# ?Detector ?n?:\s*\d*\s*(.*)\s*", re.MULTILINE)
_blockPattern = re.compile(r"^ ?# ?Block ?n?:\s*\d*\s*(.*)\s*", re.MULTILINE)
# -------------------------------------------------------------------------------
# Unpack an array of floating point numbers
# -------------------------------------------------------------------------------
[docs]def unpackArray(data):
return struct.unpack("=%df" % (len(data) // 4), data)
# ===============================================================================
# Empty class to fill with detector data
# ===============================================================================
# ===============================================================================
# Base class for all detectors
# ===============================================================================
[docs]class Usrxxx:
def __init__(self, filename=None):
"""Initialize a USRxxx structure"""
self.reset()
if filename is None:
return
f = self.readHeader(filename)
if f is not None and not f.closed:
f.close()
# ----------------------------------------------------------------------
[docs] def reset(self):
"""Reset header information"""
self.file = ""
self.title = ""
self.time = ""
self.weight = 0
self.ncase = 0
self.nbatch = 0
self.detector = []
self.seekpos = -1
self.statpos = -1
# ----------------------------------------------------------------------
# Read information from USRxxx file
# @return the handle to the file opened
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# Read detector data
# ----------------------------------------------------------------------
[docs] def readData(self, det):
"""Read detector det data structure"""
f = open(self.file, "rb")
fortran.skip(f) # Skip header
for _ in range(2 * det):
fortran.skip(f) # Detector Header & Data
fortran.skip(f) # Detector Header
data = fortran.read(f)
f.close()
return data
# ----------------------------------------------------------------------
# Read detector statistical data
# ----------------------------------------------------------------------
[docs] def readStat(self, det):
"""Read detector det statistical data"""
if self.statpos < 0:
return None
f = open(self.file, "rb")
f.seek(self.statpos)
for _ in range(det):
fortran.skip(f) # Detector Data
data = fortran.read(f)
f.close()
return data
# ----------------------------------------------------------------------
# ===============================================================================
# Residual nuclei detector
# ===============================================================================
[docs]class Resnuclei(Usrxxx):
# ----------------------------------------------------------------------
# Read information from a RESNUCLEi file
# Fill the self.detector structure
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# Read detector data
# ----------------------------------------------------------------------
[docs] def readData(self, n):
"""Read detector det data structure"""
f = open(self.file, "rb")
fortran.skip(f)
if self.evol:
fortran.skip(f)
for _ in range(n):
fortran.skip(f) # Detector Header & Data
if self.evol:
fortran.skip(f) # TDecay
fortran.skip(f) # Detector data
if self.nisomers:
fortran.skip(f) # Isomers header
fortran.skip(f) # Isomers data
fortran.skip(f) # Detector Header & Data
if self.evol:
fortran.skip(f) # TDecay
data = fortran.read(f) # Detector data
f.close()
return data
# ----------------------------------------------------------------------
# Read detector statistical data
# ----------------------------------------------------------------------
[docs] def readStat(self, n):
"""Read detector det statistical data"""
if self.statpos < 0:
return None
f = open(self.file, "rb")
f.seek(self.statpos)
f.seek(self.statpos)
if self.nisomers:
nskip = 7 * n
else:
nskip = 6 * n
for i in range(nskip):
fortran.skip(f) # Detector Data
total = fortran.read(f)
A = fortran.read(f)
errA = fortran.read(f)
Z = fortran.read(f)
errZ = fortran.read(f)
data = fortran.read(f)
if self.nisomers:
iso = fortran.read(f)
else:
iso = None
f.close()
return total, A, errA, Z, errZ, data, iso
# ----------------------------------------------------------------------
[docs] def say(self, det=None):
"""print header/detector information"""
if det is None:
self.sayHeader()
else:
bin = self.detector[det]
say("Bin : ", bin.nb)
say("Title : ", bin.name)
say("Type : ", bin.type)
say("Region : ", bin.region)
say("Volume : ", bin.volume)
say("Mhigh : ", bin.mhigh)
say("Zhigh : ", bin.zhigh)
say("NMZmin : ", bin.nmzmin)
# ===============================================================================
# Usrbdx Boundary Crossing detector
# ===============================================================================
[docs]class Usrbdx(Usrxxx):
# ----------------------------------------------------------------------
# Read information from a USRBDX file
# Fill the self.detector structure
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# Read detector data
# ----------------------------------------------------------------------
[docs] def readData(self, n):
"""Read detector n data structure"""
f = open(self.file, "rb")
fortran.skip(f)
for i in range(n):
fortran.skip(f) # Detector Header
if self.detector[i].lowneu:
fortran.skip(f) # Detector low energy neutron groups
fortran.skip(f) # Detector data
fortran.skip(f) # Detector Header
if self.detector[n].lowneu:
fortran.skip(f) # Detector low energy neutron groups
data = fortran.read(f) # Detector data
f.close()
return data
# ----------------------------------------------------------------------
# Read detector statistical data
# ----------------------------------------------------------------------
[docs] def readStat(self, n):
"""Read detector n statistical data"""
if self.statpos < 0:
return None
f = open(self.file, "rb")
f.seek(self.statpos)
for i in range(n):
for j in range(7):
fortran.skip(f) # Detector Data
for j in range(6):
fortran.skip(f) # Detector Data
data = fortran.read(f)
f.close()
return data
# ----------------------------------------------------------------------
[docs] def say(self, det=None):
"""print header/detector information"""
if det is None:
self.sayHeader()
else:
det = self.detector[det]
say("BDX : ", det.nb)
say("Title : ", det.name)
say("Type : ", det.type)
say("Dist : ", det.dist)
say("Reg1 : ", det.reg1)
say("Reg2 : ", det.reg2)
say("Area : ", det.area)
say("2way : ", det.twoway)
say("Fluence: ", det.fluence)
say("LowNeu : ", det.lowneu)
say("Energy : [", det.elow, "..", det.ehigh, "] ne=", det.ne, "de=", det.de)
if det.lowneu:
say("LOWNeut : [", det.egroup[-1], "..", det.egroup[0], "] ne=", det.ngroup)
say("Angle : [", det.alow, "..", det.ahigh, "] na=", det.na, "da=", det.da)
say("Total : ", det.total, "+/-", det.totalerror)
# ===============================================================================
# Usrtrack detector
# ===============================================================================
[docs]class UsrTrack(Usrxxx):
# ----------------------------------------------------------------------
# Read information from TRACK file
# Fill the self.detector structure
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# Read detector data
# ----------------------------------------------------------------------
[docs] def readData(self, n):
"""Read detector n data structure"""
f = open(self.file, "rb")
fortran.skip(f)
for i in range(n):
fortran.skip(f) # Detector Header
if self.detector[i].low_en_neutr_sc:
fortran.skip(f) # Detector low energy neutron groups
fortran.skip(f) # Detector data
fortran.skip(f) # Detector Header
if self.detector[n].low_en_neutr_sc:
fortran.skip(f) # Detector low energy neutron groups
data = fortran.read(f) # Detector data
f.close()
return data
# ----------------------------------------------------------------------
# Read detector statistical data
# ----------------------------------------------------------------------
[docs] def readStat(self, n):
"""Read detector n statistical data"""
if self.statpos < 0:
return None
f = open(self.file, "rb")
f.seek(self.statpos)
for i in range(n):
fortran.skip(f) # Detector Data
data = fortran.read(f)
f.close()
return data
# ----------------------------------------------------------------------
[docs] def say(self, det=None):
"""print header/detector information"""
if det is None:
self.sayHeader()
else:
bin = self.detector[det]
say("Bin : ", bin.nb)
say("Title : ", bin.name)
say("Type : ", bin.type)
say("E : [", bin.elow, "-", bin.ehigh, "] x", bin.ne, "dx=", bin.de)
# ===============================================================================
# Usrbin detector
# ===============================================================================
[docs]class Usrbin(Usrxxx):
# ----------------------------------------------------------------------
# Read information from USRBIN file
# Fill the self.detector structure
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# Read detector data
# ----------------------------------------------------------------------
[docs] def readData(self, n):
"""Read detector det data structure"""
f = open(self.file, "rb")
fortran.skip(f)
for _ in range(n):
fortran.skip(f) # Detector Header
fortran.skip(f) # Detector data
fortran.skip(f) # Detector Header
data = fortran.read(f) # Detector data
f.close()
return data
# ----------------------------------------------------------------------
# Read detector statistical data
# ----------------------------------------------------------------------
[docs] def readStat(self, n):
"""Read detector n statistical data"""
if self.statpos < 0:
return None
f = open(self.file, "rb")
f.seek(self.statpos)
for _ in range(n):
fortran.skip(f) # Detector Data
data = fortran.read(f)
f.close()
return data
# ----------------------------------------------------------------------
[docs] def say(self, det=None):
"""print header/detector information"""
if det is None:
self.sayHeader()
else:
bin = self.detector[det]
say("Bin : ", bin.nb)
say("Title : ", bin.name)
say("Type : ", bin.type)
say("Score : ", bin.score)
say("X : [", bin.xlow, "-", bin.xhigh, "] x", bin.nx, "dx=", bin.dx)
say("Y : [", bin.ylow, "-", bin.yhigh, "] x", bin.ny, "dy=", bin.dy)
say("Z : [", bin.zlow, "-", bin.zhigh, "] x", bin.nz, "dz=", bin.dz)
say("L : ", bin.lntzer)
say("bk : ", bin.bk)
say("b2 : ", bin.b2)
say("tc : ", bin.tc)
# ===============================================================================
# MGDRAW output
# ===============================================================================
[docs]class Mgdraw:
def __init__(self, filename=None):
"""Initialize a MGDRAW structure"""
self.reset()
if filename is None:
return
self.open(filename)
# ----------------------------------------------------------------------
[docs] def reset(self):
"""Reset information"""
self.file = ""
self.hnd = None
self.nevent = 0
self.data = None
# ----------------------------------------------------------------------
# Open file and return handle
# ----------------------------------------------------------------------
[docs] def open(self, filename):
"""Read header information, and return the file handle"""
self.reset()
self.file = filename
try:
self.hnd = open(self.file, "rb")
except IOError:
self.hnd = None
return self.hnd
# ----------------------------------------------------------------------
[docs] def close(self):
self.hnd.close()
# ----------------------------------------------------------------------
# Read or skip next event from mgread structure
# ----------------------------------------------------------------------
[docs] def readEvent(self, e_type=None):
# Read header
data = fortran.read(self.hnd)
if data is None:
return None
if len(data) == 20:
ndum, mdum, jdum, edum, wdum = struct.unpack("=iiiff", data)
else:
raise IOError("Invalid MGREAD file")
self.nevent += 1
if ndum > 0:
if e_type is None or e_type == 0:
self.readTracking(ndum, mdum, jdum, edum, wdum)
else:
fortran.skip(self.hnd)
return 0
elif ndum == 0:
if e_type is None or e_type == 1:
self.readEnergy(mdum, jdum, edum, wdum)
else:
fortran.skip(self.hnd)
return 1
else:
if e_type is None or e_type == 2:
self.readSource(-ndum, mdum, jdum, edum, wdum)
else:
fortran.skip(self.hnd)
return 2
# ----------------------------------------------------------------------
[docs] def readTracking(self, ntrack, mtrack, jtrack, etrack, wtrack):
self.ntrack = ntrack
self.mtrack = mtrack
self.jtrack = jtrack
self.etrack = etrack
self.wtrack = wtrack
data = fortran.read(self.hnd)
if data is None:
raise IOError("Invalid track event")
fmt = "=%df" % (3 * (ntrack + 1) + mtrack + 1)
self.data = struct.unpack(fmt, data)
return ntrack
# ----------------------------------------------------------------------
[docs] def readEnergy(self, icode, jtrack, etrack, wtrack):
self.icode = icode
self.jtrack = jtrack
self.etrack = etrack
self.wtrack = wtrack
data = fortran.read(self.hnd)
if data is None:
raise IOError("Invalid energy deposition event")
self.data = struct.unpack("=4f", data)
return icode
# ----------------------------------------------------------------------
[docs] def readSource(self, ncase, npflka, nstmax, tkesum, weipri):
self.ncase = ncase
self.npflka = npflka
self.nstmax = nstmax
self.tkesum = tkesum
self.weipri = weipri
data = fortran.read(self.hnd)
if data is None:
raise IOError("Invalid source event")
fmt = "=" + ("i8f" * npflka)
self.data = struct.unpack(fmt, data)
return ncase
# ===============================================================================
if __name__ == "__main__":
import sys
say("=" * 80)
usr = Usrbdx(sys.argv[1])
usr.say()
for i, _ in enumerate(usr.detector):
say("-" * 50)
usr.say(i)
data = unpackArray(usr.readData(i))
stat = unpackArray(usr.readStat(i))