예제 #1
0
def getFamilyAttributeSum(center2,r,family,attribute):
    """Integrates attributes of a given family over a given sphere."""
    charm.createGroupAttributeSphere('group', 'All', 'position', center2[0], center2[1], center2[2], r)
    charm.createGroup_Family('group','group',family)
    sum = charm.getAttributeSum('group', family, attribute)
    charm.deleteGroup('group')
    return sum
예제 #2
0
 def getGalDensity(center2, r):
     charm.createGroupAttributeSphere(virialGroup, "All", "position", center[0], center[1], center[2], r)
     totMass = 0.0
     for fam in charm.getFamilies():
         totMass += charm.getAttributeSum(virialGroup, fam, "mass")
     v = (4 * math.pi / 3.0) * r ** 3
     density = totMass / v
     return density
예제 #3
0
def getNormalStarAngMom(center2, radius, comVel=None):
    """Calculates the stellar angular momentum vector given a center and radius. By default the COM velocity is calculated unless it is passed."""
    if (comVel==None):vCM=getVelCMStars(center2, radius)
    else: vCM = comVel 
    charm.createGroupAttributeSphere('groupAll', 'All', 'position', center2[0], center2[1], center2[2], radius) 
    charm.createGroup_Family('groupStar', 'groupAll', 'star')
    starAngMom1  = charm.reduceParticle('groupStar', getParticleAngMomentum, sumAngMomentum, [center2,vCM])
    starAngMom = (starAngMom1[0][1],starAngMom1[0][2],starAngMom1[0][3])
    starAngMomMag = math.sqrt(starAngMom[0]**2+starAngMom[1]**2+starAngMom[2]**2)
    starAngMom = (starAngMom[0]/starAngMomMag,starAngMom[1]/starAngMomMag,starAngMom[2]/starAngMomMag)
    return  starAngMom
예제 #4
0
def setsphere(group, *args) :
  """Select particles within radius from coordinate."""
  import charm
  try :
    # parse args
    if len(args) < 3 : raise TypeError('Too few arguments')
    if type(args[0]) == str :
        if args[0] == 'pot' or args[0] == 'potential ':
            center = charm.findAttributeMin(args[1], 'potential')
            radius = args[2]
            if(len(args) == 4) : parent = args[3]
            else : parent = 'All'
        elif args[0] == 'com' :
            if type(args[1]) != str : raise StandardError('third argument should be a group')
            if args[2] == 'all' or args[2] == 'All' :
                center = charm.getCenterOfMass(args[1])
                radius = args[3]
                if(len(args) == 5) : parent = args[4]
                else : parent = 'All'
            elif args[2] == 'gas' :
                charm.createGroup_Family("__tmpgroup", args[1], 'gas')
                center = charm.getCenterOfMass(args[1])
                radius = args[3]
                if(len(args) == 5) : parent = args[4]
                else : parent = 'All'
            elif args[2] == 'dark' :
                charm.createGroup_Family("__tmpgroup", args[1], 'dark')
                center = charm.getCenterOfMass(args[1])
                radius = args[3]
                if(len(args) == 5) : parent = args[4]
                else : parent = 'All'
            elif args[2] == 'star' :
                charm.createGroup_Family("__tmpgroup", args[1], 'star')
                center = charm.getCenterOfMass(args[1])
                radius = args[3]
                if(len(args) == 5) : parent = args[4]
                else : parent = 'All'
            else : raise StandardError('unknown particle type: ' + args[2])
        else : raise StandardError('unknown center type: ' + args[0])
    else :
        center = (args[0], args[1], args[2])
        radius = args[3]
        if(len(args) == 5) : parent = args[4]
        else : parent = 'All'

    # check if simulation loaded
    if charm.getGroups() == None :
        raise StandardError('Simulation not loaded')

    charm.createGroupAttributeSphere(group, parent, 'position', center[0], center[1],
                                     center[2], radius)
  except :
      print traceback.format_exc()
예제 #5
0
def findCenter(group2='All', method = 'pot' ):
    """Finds the center of a given group based on method as 'com' or 'pot'"""
    if (method=='pot'): 
        if (group2=='All'):  
            charm.createGroup_AttributeRange('highres', 'All', 'mass', -1, 7e-12)
            cntHr =  charm.getCenterOfMass('highres')
            charm.createGroupAttributeSphere('centerhr', 'All', 'position', cntHr[0], cntHr[1], cntHr[2], 1000./136986.30137)
            cnt = charm.findAttributeMin('centerhr', 'potential')
        else:
            cnt = charm.findAttributeMin(group2, 'potential')
    elif (method=='com'):
        cnt = charm.getCenterOfMass(group2)
    return cnt
예제 #6
0
def getVelCMStars(center2, radius):
    "Returns the vector for the center of mass velocity of a group of stars defined by center2 coordinates and a radius."
    charm.createGroupAttributeSphere('tmpGal', 'All', 'position', center2[0], center2[1], center2[2], radius) #use cmVelCompare2.py to choose length
    charm.createGroup_Family('tmpStarGroup', 'tmpGal', 'star') #select star particles only
    massStar = charm.getAttributeSum('tmpGal', 'star', 'mass')
    mass = massStar #calculate total mass
    vmomentStar = charm.reduceParticle('tmpStarGroup', centMassVelMap, centMassReduce, None)
    vmoment = [vmomentStar[0][1],vmomentStar[0][2],vmomentStar[0][3]]
    vcm = (vmoment[0]/mass, vmoment[1]/mass, vmoment[2]/mass)
    #Clean up
    charm.deleteGroup('tmpGal')
    charm.deleteGroup('tmpStarGroup')
    return vcm #return the COM velocity vector    
예제 #7
0
def calcGalacticCoordinates(angMomGroup=None, center ='pot'):
    '''Assigns particles a position in the galactic coordinate system. galVelocity = (v+Hr).  angMomGroup'''
    #===========================================================================
    # --Overview--
    # 1.Form transformation matrix
    # 2.Translate the coordinates to the center of the galaxy (or COM velocity)
    # 3.Rotate the coordinate system to be aligned with the angular momentum vector
    # 4.Write information to vector attributes
    #===========================================================================
    if ((angMomGroup in charm.getGroups())==False) & (angMomGroup!=None):
        print "Group does not exist, please try again."
        return
    ##############################
    # Actual Routine
    ##############################
    if (angMomGroup==None):
        angMomGroup = 'angMomGroup'
        cnt = findcenter.findCenter(method=center)
        virialRadius = virialgroup.getVirialGroup()
        charm.createGroupAttributeSphere('angMomGroup', 'All', 'position', cnt[0], cnt[1], cnt[2], virialRadius*quesoConfig.rgalFraction)
        charm.createGroup_Family('angMomGroup', 'angMomGroup', 'gas')
        charm.createGroup_AttributeRange('angMomGroup', 'angMomGroup', 'temperature', 0, quesoConfig.coldGasTemp)
    else: 
        cnt = findcenter.findCenter(group2=angMomGroup,method=center)
        
    angmom.getAngMomVector(group=angMomGroup,center=center)
    # Transformation Matrix
    galZ = vectormath.normalizeVector(angmom.getAngMomVector(group=angMomGroup,center=center))
    galX = vectormath.normalizeVector(vectormath.crossVectors((0,1,0),galZ))
    galY = vectormath.normalizeVector(vectormath.crossVectors(galZ,galX))
    transMatrix = (galX,
                   galY,
                   galZ)
    
    fHubble       = quesoConfig.fHubble0*math.sqrt(quesoConfig.omega0/charm.getTime()**3+(1-quesoConfig.omega0))
    # Galactic Position                    
    charm.createVectorAttribute('star','galPosition')
    charm.createVectorAttribute('gas', 'galPosition')
    charm.createVectorAttribute('dark','galPosition')
    param = (cnt, transMatrix)
    charm.runLocalParticleCodeGroup('All', calcGalPosition, param)
    # Galactic velocity
    vCM=angmom.getVelCM(angMomGroup)
    param = (cnt, transMatrix,vCM, fHubble)
    charm.createVectorAttribute('star','galVelocity')
    charm.createVectorAttribute('gas', 'galVelocity')
    charm.createVectorAttribute('dark','galVelocity')
    charm.runLocalParticleCodeGroup('All', calcGalVelocity, param)
    return
예제 #8
0
def SFRSurfaceProfile(minRadius=.1, numBins=50,tstep='00512',nbins=500):
    """Returns the list of tuples (radius, SFR, diskSFR, bulgeSFR) in solar masses/year! (for the 0.5Gyr preceding each time)"""
    #read in initial masses from file
    filename = quesoConfig.dataDir + quesoConfig.preTimestepFilename + tstep + ".massform"
    charm.readTipsyArray(filename,'initialMass')
    
    virialRadius = virialgroup.getVirialGroup()
    rgal = quesoConfig.rgalFraction*virialRadius
    center = findcenter.findCenter()       
    radialStep  = ((math.log10(rgal)-math.log10(minRadius))/(float(numBins)-1))
    simTime = getSimTime(timestep=tstep)/quesoConfig.timeunit #time in simulation units
    sfr = [[]]*numBins
    #initialize relevant attributes
    galcoord.calcGalacticCoordinates()
    
    #create sphere of stars
    charm.createGroupAttributeSphere('galStar', 'All', 'position', center[0], center[1], center[2], rgal) 
    charm.createGroup_Family('galStar', 'galStar', 'star')
    formHigh = simTime
    formLow  = formHigh-quesoConfig.sfrLookback/quesoConfig.timeunit
    param = (formLow, formHigh, radialStep, quesoConfig.kpcunit*charm.getTime(), minRadius)
    reduceResult = charm.reduceParticle('galStar' , mapSFRProfile, reduceSFRProfile, param)
    print reduceResult
    print (formLow,formHigh)
    maxbin=0
    
    for i in range(0,len(reduceResult)):
        if (reduceResult[i][0]>maxbin):maxbin=reduceResult[i][0]
    for i in range(0,len(reduceResult)):
        radiusOut = math.pow(10, radialStep*reduceResult[i][0])
        radiusInside = math.pow(10, radialStep*(reduceResult[i][0]-1))
        radius = (radiusOut+radiusInside)/2
        area  = math.pi*(radiusOut**2-radiusInside**2)
        formationRate      = reduceResult[i][1]*quesoConfig.msolunit/quesoConfig.sfrLookback/area #msolar/yr/kpc^2
        bin = reduceResult[i][0]+numBins-maxbin-1
        sfr[bin]=(radius, formationRate)
        print sfr[bin]
    for i in range(0,numBins):
        if (sfr[i] == []):
            radiusOut = math.pow(10, radialStep*(i+1))
            radiusInside = math.pow(10, radialStep*i)
            radius = (radiusOut+radiusInside)/2
            sfr[i]=(radius,0,0,0) 
    sfrData = [[],[]]        
    for i in range(len(sfr)):
        sfrData[0].append(sfr[i][0])
        sfrData[1].append(sfr[i][1])
    return sfrData
예제 #9
0
def getSFRTimeProfile(nbins=500):
    """Returns the list of tuples (time, SFR) in solar masses/year! (for the 0.5Gyr preceding each time)"""
    #read in initial masses from file
    filename = quesoConfig.dataDir + quesoConfig.preTimestepFilename + quesoConfig.nTimesteps + ".massform"
    charm.readTipsyArray(filename,'initialMass')
    
    simTime = getSimTime()/quesoConfig.timeunit #time in simulation units
    profileTStep = simTime/nbins
    sfr = [(0,0)]*nbins
    center = findcenter.findCenter()
    rgal = virialgroup.getVirialGroup()*quesoConfig.rgalFraction
    charm.createGroupAttributeSphere('galStar', 'star', 'position', center[0], center[1], center[2], rgal) #Particles within galactic radius
    charm.createGroup_Family('galStar', 'galStar', 'star')
    param = (profileTStep, nbins)
    reduceResult = charm.reduceParticle('galStar' , mapSFR, reduceSFR, param) 
    #sum = 0.0
    for i in range(0,len(reduceResult)):
        #try:
        formationRate      = reduceResult[i][1]*quesoConfig.msolunit/(profileTStep*quesoConfig.timeunit) #msolar/yr
        age = (simTime -reduceResult[i][0]*profileTStep)*quesoConfig.timeunit/1e9 #in gyr
        sfr[reduceResult[i][0]-1] =(age, formationRate)
    return sfr
예제 #10
0
def getEpsilonDist(group='gal', nBins=50, epsCut=2., center='pot'):
    """Returns a histogram of dimension 2 x nbins of stellar epsilons (jz/jcirc) and mass-fraction.  epsCut defines the histogram bound in both directions. Center can be either 'pot' or 'com'"""
    numRotBins   = 400 #number of points at which we linearly interpolate 
    radiusVCM    = 0.25 #fraction of group radius to use when calculating COM velocity
    radiusAngMom = 0.25 #fraction of group radius to use when calculating stellar angular momentum
    
    
    a = charm.getTime()
    if ((group in charm.getGroups()==False)) & (group !='gal'):
        print "Group does not exist, please try again."
        return
    if (group == 'gal'): 
        rgal = quesoConfig.rgalFraction*virialgroup.getVirialGroup()
        center=findcenter.findCenter(group2='virialGroup', method=center)
        charm.createGroupAttributeSphere('gal', 'All', 'position', center[0], center[1], center[2], rgal)
    else:
        center=findcenter.findCenter(group2=group, method=center)
        
    # Find maximum radius
    charm.createGroup_Family('tmp',group,'star')
    maxRad = getgroupradius.getGroupRadius('tmp', center)
    massDist = [0]*(numRotBins+1)
    rad = [0]*(numRotBins+1)
    radialStep = maxRad/numRotBins
    #populate mass bins
    for i in range(numRotBins+1): 
        charm.createGroupAttributeSphere('tmp', 'All', 'position', center[0], center[1], center[2], radialStep*i)
        massDist[i]  = charm.getAttributeSum('tmp','star','mass')
        massDist[i] += charm.getAttributeSum('tmp','dark','mass')
        massDist[i] += charm.getAttributeSum('tmp','gas' ,'mass')
        #Note: I tried shells instead of spheres and it made no real difference.
        rad[i] = radialStep*i
        
    vCM = getVelCMStars(center2=center, radius=radiusVCM*maxRad) #COM velocity
    angMomVec = getNormalStarAngMom(center2=center, radius=radiusAngMom*maxRad, comVel=vCM) #Ang Mom Velocity
    #vCM = getVelCMStars(center2=center, radius=10/(a*quesoConfig.kpcunit)) #COM velocity
    #angMomVec = getNormalStarAngMom(center2=center, radius=6/(a*quesoConfig.kpcunit), comVel=vCM) #Ang Mom Velocity
    
    param = (center, vCM, angMomVec, maxRad, numRotBins,massDist, nBins,epsCut)
    charm.createGroupAttributeSphere('tmp', 'All', 'position', center[0], center[1], center[2], maxRad)
    charm.createGroup_Family('tmp',group,'star')
    #calc total stellar mass for mass weighted average
    reduceResult = charm.reduceParticle('tmp', mapEpsilon, reduceEpsilon, param) 
    sMass = charm.getAttributeSum('tmp','star', 'mass')
    epsilonDist = [0]*nBins
    eps  = [0]*nBins
    for i in range(nBins): eps[i] = -epsCut+ 2*epsCut/nBins*(i)
    for i in range(len(reduceResult)):
        try:
            bin = reduceResult[i][0]
            epsilonDist[bin] = reduceResult[i][1]/sMass #return the mass fraction
        except:{}
    return (eps, epsilonDist)
예제 #11
0
def getVirialGroup(group="All", center2="pot", virialGroup="virialGroup"):
    """This method returns the virial radius of a given group, bases around a center that can be given by one of three options: Default 'pot' finds the potential minimum, 'com' uses the center of mass, or a tuple of length 3 can be given.  virialGroup specifies the group name of the resulting """
    global center
    if center2 == "pot":
        cnt = findcenter.findCenter(group2=group, method="pot")
    elif center2 == "com":
        cnt = findcenter.findCenter(group2=group, method="com")
    elif len(center2) == 3:
        cnt = center2
    center = cnt  # use center variable at later times.
    # ===========================================================================
    # Use center coordinates to find virial radius and return group
    # Returns virial radius in sim units via bisection method.
    # If this doesn't converge, try larger bounds or adjust the
    # other parameters in source.
    # ===========================================================================
    def getGalDensity(center2, r):
        charm.createGroupAttributeSphere(virialGroup, "All", "position", center[0], center[1], center[2], r)
        totMass = 0.0
        for fam in charm.getFamilies():
            totMass += charm.getAttributeSum(virialGroup, fam, "mass")
        v = (4 * math.pi / 3.0) * r ** 3
        density = totMass / v
        return density

    # ================================================================
    # Specify bounds of bisection.  Default is 0.1 to 400kpc (at redshift zero)
    epsilon = 0.001  # maximum error in density convergence
    count = 0
    maxIterations = 200
    leftr = 0.1 / quesoConfig.kpcunit
    rightr = 4000.0 / quesoConfig.kpcunit
    # ================================================================
    from queso.quesoConfig import virialRadiusDensity

    midpoint = (leftr + rightr) / 2
    leftDensity = getGalDensity(center, leftr) - virialRadiusDensity  # Initialize values
    rightDensity = getGalDensity(center, rightr) - virialRadiusDensity  # offset so we can find root
    midDensity = getGalDensity(center, midpoint) - virialRadiusDensity  # offset so we can find root
    # Bisection to find virial radius as defined in quesoConfig
    # Run until values converge within epsilon or reach max count
    while (count < maxIterations) & (math.fabs(leftDensity - rightDensity) > epsilon):
        midpoint = (leftr + rightr) / 2
        leftDensity = getGalDensity(center, leftr) - virialRadiusDensity  # offset so we can find root
        rightDensity = getGalDensity(center, rightr) - virialRadiusDensity  # offset so we can find root
        midDensity = getGalDensity(center, midpoint) - virialRadiusDensity  # offset so we can find root
        if leftDensity * midDensity < 0:
            rightr = midpoint
        elif rightDensity * midDensity < 0:
            leftr = midpoint
        elif midDensity == 0:
            break
        elif (leftDensity * midDensity > 0) & (rightDensity * midDensity > 0):
            print "\nVirial radius calculation will not converge. Try larger bounds."
            return
        count += 1
    # Don't get stuck in a loop
    if count == maxIterations:
        print "\nDid not converge in " + str(
            maxIterations
        ) + " iterations.  Try smaller bounds or raise epsilon in source."
        return
    charm.createGroupAttributeSphere(virialGroup, "All", "position", center[0], center[1], center[2], midpoint)
    return midpoint  # in sim units
예제 #12
0
def writeBoxAscii(boxRadius, filename, angMomGroup=None, centerMethod ='pot'):
    """Writes out an tipsy-ascii (filename) representation for a box aligned with the galactic coordinate system spanning +-boxRadius (given in kpc) in the galcoord directions. center can be 'pot' or 'com'.  Default angMomGroup is cold galactic gas."""
    if (angMomGroup==None):
        angMomGroup = 'angMomGroup'
        center = findcenter.findCenter(method=centerMethod)
        virialRadius = virialgroup.getVirialGroup()
        charm.createGroupAttributeSphere('angMomGroup', 'All', 'position', center[0], center[1], center[2], virialRadius*quesoConfig.rgalFraction)
        charm.createGroup_Family('angMomGroup', 'angMomGroup', 'gas')
        charm.createGroup_AttributeRange('angMomGroup', 'angMomGroup', 'temperature', 0, quesoConfig.coldGasTemp)
    else: 
        center = findcenter.findCenter(group2=angMomGroup,method=center)
        
    boxRad1 = boxRadius/(charm.getTime()*quesoConfig.kpcunit)
    print 'here'
    galcoord.calcGalacticCoordinates(angMomGroup=angMomGroup, center=centerMethod)
    galZ = vectormath.normalizeVector(angmom.getAngMomVector(angMomGroup))
    galX = vectormath.normalizeVector(vectormath.crossVectors((0,1,0),galZ))
    galY = vectormath.normalizeVector(vectormath.crossVectors(galZ,galX))
    #===========================================================================
    # Create the cube
    #===========================================================================
    cornerVec = vectormath.addVectors(vectormath.multVectorScalar(boxRad1, galX),vectormath.multVectorScalar(boxRad1, galY))
    cornerVec = vectormath.addVectors(cornerVec,vectormath.multVectorScalar(boxRad1, galZ))
    cornerVec = vectormath.subVectors(center, cornerVec)
    edge1 = vectormath.multVectorScalar(2*boxRad1,galX)
    edge2 = vectormath.multVectorScalar(2*boxRad1,galY)
    edge3 = vectormath.multVectorScalar(2*boxRad1,galZ)
    charm.createGroupAttributeBox('galBox', 'All', 'position',
                                  cornerVec[0],cornerVec[1],cornerVec[2],
                                  edge1[0]    ,edge1[1]    ,edge1[2],
                                  edge2[0]    ,edge2[1]    ,edge2[2],
                                  edge3[0]    ,edge3[1]    ,edge3[2])
    numStars = charm.getNumParticles('galBox','star')
    numGas   = charm.getNumParticles('galBox','gas')
    numDark  = charm.getNumParticles('galBox','dark')
    numTotal = numStars + numGas + numDark
    #===========================================================================
    # This region outputs the ascii file to be read in by tipsy
    #===========================================================================
    f = open(filename, 'w') # overwrites pre-existing file
    f.write(str(numTotal) + ' ' + str(numGas) + ' ' + str(numStars))
    f.write('\n3')
    f.write('\n'+ str(charm.getTime())+ '\n')
    f.close()
    for each in ['star','dark','gas']:charm.createScalarAttribute(each, 'tmpWorking')
    def writeAndAppend(attribute):
        charm.writeGroupArray('tmpGalBox', attribute, '/tmp/out.tmp')
        os.system('tail -n +2 /tmp/out.tmp >> ' + filename)
        return
    families = ['gas','dark','star']
    for each in families:
        charm.createGroup_Family('tmpGalBox', 'galBox', each)
        writeAndAppend('mass')
    # Positions
    for i in range(0,3):
        for each in families:
            charm.createGroup_Family('tmpGalBox', 'galBox', each)
            charm.runLocalParticleCodeGroup('tmpGalBox', vectorWriter, ('pos', i))
            writeAndAppend('tmpWorking')
    # Velocities
    for i in range(0,3):
        for each in families:
            charm.createGroup_Family('tmpGalBox', 'galBox', each)
            charm.runLocalParticleCodeGroup('tmpGalBox', vectorWriter, ('vel', i))
            writeAndAppend('tmpWorking')
    # Star and dark softening
    for each in ['dark', 'star']:
        charm.createGroup_Family('tmpGalBox', 'galBox', each)
        writeAndAppend('softening')        
    # Gas attributes
    charm.createGroup_Family('tmpGalBox', 'galBox', 'gas')
    for each in ['density','temperature','softening','metals']:
        writeAndAppend(each)
    #Star stuff
    charm.createGroup_Family('tmpGalBox', 'galBox', 'star')
    for each in ['metals','formationtime']:
        writeAndAppend(each)
    #potential
    for each in families:
        charm.createGroup_Family('tmpGalBox', 'galBox', each)
        writeAndAppend('potential')
    charm.deleteGroup('tmpGalBox')
    #print 'num lines in ' + filename + ' should be: ' + str(9*numTotal+3*numGas+2*numStars+3)
    return