# How can I include all eventualities?

This code takes in a 3array (position) and tests to see whether it sits in some region of the model or not. The problem is in the PbSheild method, I can't work out why though. This code will work as is (well it will not work as is, that's the point).

```class Geometry

\$polyCylFr = 15
\$polyCylB = -2.0
\$borPolyBoxL = 9.0 / 2
\$pbBoxL = 10.0 / 2
\$cdBoxL = 9.5 / 2
\$xSquared = Float
\$ySquared = Float
\$zSquared = Float
\$modX = Float
\$modY = Float
\$modZ =Float
\$position = Array.new

def checkMaterial(params)

\$position = params
\$xSquared = \$position[0] ** 2
\$ySquared = \$position[1] ** 2
\$zSquared = \$position[2] ** 2
\$modX = Math.sqrt(\$xSquared)
\$modY = Math.sqrt(\$ySquared)
\$modZ = Math.sqrt(\$zSquared)

puts "polyCyl: " + self.polyCylinder.to_s
puts "borpoly: " + self.borPolyBox.to_s
puts "Cd: " + self.CdShield.to_s
puts "Pb Cylinder: " + self.PbCylinder.to_s
puts "Pb: " + self.PbShield.to_s
puts "FreeSpace: " + self.FreeSpace.to_s

material
end

def polyCylinder
Math.sqrt(\$ySquared + \$zSquared) <= \$polyCylRad && \$position[0] >= \$polyCylB && \$position[0] <= \$polyCylFr
end

def borPolyBox
!polyCylinder && (\$modX <= \$borPolyBoxL || \$modY <= \$borPolyBoxL || \$modZ <= borPolyBoxL) && !(\$modX > \$borPolyBoxL || \$modY > \$borPolyBoxL || \$modZ > borPolyBoxL)
end

def CdShield
!polyCylinder && !borPolyBox && (\$modX <= \$cdBoxL || \$modY <= \$cdBoxL || \$modZ <= \$cdBoxL) &&  !(\$modX > \$cdBoxL || \$modY > \$cdBoxL || \$modZ > \$cdBoxL)
end

def PbCylinder
!polyCylinder && \$position[0] >= \$cdBoxL && \$position[0]  <= \$polyCylFr && Math.sqrt(\$ySquared + zSquared) <= \$pbCylRad
end

def PbShield
!polyCylinder && !borPolyBox && !CdShield && !PbCylinder && (\$modX <= \$pbBoxL || \$modY <= \$pbBoxL || \$modZ <= \$pbBoxL) && !(\$modX > \$pbBoxL || \$modY > \$pbBoxL || \$modZ > \$pbBoxL)
end

def FreeSpace
!polyCylinder && !borPolyBox && !CdShield && !PbShield && !PbCylinder
end

def material
[
[:polyCylinder, 'poly'],
[:borPolyBox, 'borPoly'],
[:CdShield, 'Cd'],
[:PbCylinder, 'Pb'],
[:PbShield, 'Pb'],
[:FreeSpace, 'air']
].each do |method, name|
return name if send(method)
end
false
end

end

\$bob = Geometry.new
posVect = Array.new
posVect << 0 << 0 << 0
\$bob.checkMaterial(posVect)

while posVect[0]  < 25 do

\$bob.checkMaterial(posVect)
puts "Xpos: " + posVect[0].to_s
puts "Ypos: " + posVect[1].to_s
puts "Zpos: " + posVect[2].to_s
puts "polyCyl: " + \$bob.polyCylinder.to_s
puts "borpoly: " + \$bob.borPolyBox.to_s
puts "Cd: " + \$bob.CdShield.to_s
puts "Pb: " + \$bob.PbShield.to_s
puts "FreeSpace: " + \$bob.FreeSpace.to_s
puts ""

posVect[0] += 1

end
```

If you think this looks suspiciously like it is related to my c++ code you are correct, am writing two structurally different monte carlo's in Ruby and c++ (learning Ruby and the deepening c++ knowledge at the same time).

Thanks!

I would rewrite this entirely. You have a couple of problems that you want to solve. First, you want to define a region and see if a point is within that region. That should probably be one module with a method for defining regions and a method for placing a point within a defined region. You could, if you wished, define the regions in the module itself, or define them on the fly, whichever. That would give you the ability to pass a region name or definition and a point to a single method and get back whether the point is within that region. That would be much easier to test.

Second, you want to determine the material value: true or false, for every material. You might consider using a case statement for this. You write a method that returns values for your region test (like :poly, :box, whatever) and then use that as the test for your case statement:

```   case whatever(point)
when (:foo)
set some values
when (:bar)
set some other values
end
```

If you set the default for every material value to false (a good plan) then you'll only have to update the trues, and it should be easy, based on the return value of your region check method, to decide what values need to be true or can be true.

Breaking the code apart this way--or some other way--will make it much easier to test.