def solve(self,scorer,initTrialPoint): """ This method applays the fitting algorithms to the problem. """ self.is_running = True self.scoreboard.init() self._setScorer(scorer) self.search_algorithm.setSolver(self) res = self.search_algorithm.setTrialPoint(initTrialPoint) if(not res): msg = "============ Solver class: method solve(...)==============" msg += os.linesep msg += "Cannot initialize the search algorithm" msg += os.linesep msg += "Stop." msg += os.linesep orbitFinalize(msg) while(not self.stopper.getShouldStop()): self.search_algorithm.makeStep() self.is_running = False self._setScorer(None)
def rebuild(self, Ekin=-1.0): if (Ekin > 0.): self.bunch.getSyncParticle().kinEnergy(Ekin) for matrixNode in self.getNodes(): if (isinstance(matrixNode, BaseMATRIX) == True): node = matrixNode.getParam("matrix_parent_node") active_index = matrixNode.getParam( "matrix_parent_node_active_index") n_parts = matrixNode.getParam("matrix_parent_node_n_nodes") if (n_parts != node.getnParts()): msg = " orbit.teapot.TEAPOT_MATRIX_Lattice class" + os.linesep msg = msg + " rebuild(Ekin = -1.0) method" + os.linesep msg = msg + " TEAPOT node=" + node.getName() + os.linesep msg = msg + " has been changed!" + os.linesep msg = msg + " Stop!" + os.linesep orbitFinalize(msg) self.matrixGenerator.initBunch(self.bunch) paramsDict = {} paramsDict["bunch"] = self.bunch paramsDict["node"] = node node.setActivePartIndex(active_index) node.track(paramsDict) self.matrixGenerator.calculateMatrix(self.bunch, matrixNode.getMatrix()) self.makeOneTurnMatrix()
def getNodeForName(self,name): """ Method. Returns the node with certain name. """ nodes = [] for node in self.__children: if(node.getName().find(name) == 0): nodes.append(node) if(len(nodes) == 1): return nodes[0] else: if(len(nodes) == 0): return None else: msg = "The AccLattice class. Method getNodeForName found many nodes instead of one!" msg = msg + os.linesep msg = msg + "looking for name=",name msg = msg + os.linesep msg = msg + "found nodes:" for node in nodes: msg = msg + " " + node.getName() msg = msg + os.linesep msg = "Please use getNodesForName method instead." msg = msg + os.linesep orbitFinalize(msg)
def filterSequences_and_OptionalCheck(self,accSeq_da_arr,names): """ This method will filter the sequences according to names list and check the order of sequences in names. All sequences should be in the right order. For SNS linac is just a linac. It returns the filtered array with data adapters with the names in the names array. """ seqencesLocal = accSeq_da_arr seqencesLocalNames = [] for seq_da in seqencesLocal: seqencesLocalNames.append(seq_da.getName()) ind_old = -1 count = 0 for name in names: ind = seqencesLocalNames.index(name) if(ind < 0 or (count > 0 and ind != (ind_old + 1))): msg = "The LinacLatticeFactory method getLinacAccLattice(names): sequence names array is wrong!" msg = msg + os.linesep msg = msg + "existing names=" + str(seqencesLocalNames) msg = msg + os.linesep msg = msg + "sequence names="+str(names) orbitFinalize(msg) ind_old = ind count += 1 ind_start = seqencesLocalNames.index(names[0]) accSeq_da_arr = accSeq_da_arr[ind_start:ind_start+len(names)] return accSeq_da_arr
def initialize(self): """ The Bend Combined Functions TEAPOT class implementation of the AccNode class initialize() method. """ nParts = self.getnParts() if (nParts < 2): msg = "The Bend Combined Functions TEAPOT class instance should have more than 2 parts!" msg = msg + os.linesep msg = msg + "Method initialize():" msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep msg = msg + "nParts =" + str(nParts) orbitFinalize(msg) rho = self.getLength() / self.getParam("theta") self.addParam("rho", rho) lengthIN = (self.getLength() / (nParts - 1)) / 2.0 lengthOUT = (self.getLength() / (nParts - 1)) / 2.0 lengthStep = lengthIN + lengthOUT self.setLength(lengthIN, 0) self.setLength(lengthOUT, nParts - 1) for i in xrange(nParts - 2): self.setLength(lengthStep, i + 1)
def addChildNode(self, node, place, part_index=0, place_in_part=AccActionsContainer.BEFORE): """ Method. Adds a child node to the list defined by place and (maybe) part index and place in the part (before or after). The action of the child occurs after the action of the parent at the entrance and before at the exit. """ nodes = None if (place == AccNode.ENTRANCE or place == AccNode.EXIT): nodes = self.__childNodesArr[place] else: if (place != AccNode.BODY): msg = "The Class AccNode: error in method addChildNode(node,place,part_index,place_in_part)!" msg = msg + os.linesep msg = msg + "place parameter should be AccNode.ENTRANCE, AccNode.BODY, or AccNode.EXIT!" msg = msg + os.linesep msg = msg + "You specified place=" + place msg = msg + os.linesep msg = msg + "(part_index,place_in_part) =" + (part_index, place_in_part) msg = msg + os.linesep msg = msg + "Fix it!" msg = msg + os.linesep orbitFinalize(msg) nodes = self.__childNodesArr[place][part_index][place_in_part] nodes.append(node)
def setGaussDistributedDisplacementParameter(self, key, value, cut_off_level=3.0, comm=mpi_comm.MPI_COMM_WORLD): """ Sets the random generated error value for a particular coordinate for all nodes. The cooridinate is defined by key parameter. """ value = abs(value) if (self.param_dict.has_key(key)): self.param_dict[key] = value else: msg = "Class CoordinateDisplacementNodesModification - key-value problem" msg = msg + os.linesep msg = msg + "Method setGaussDistributedDisplacementParameter:" msg = msg + os.linesep msg = msg + "You are trying to set value for key=" + key msg = msg + os.linesep msg = msg + "Keys could be only = (dx, dxp, dy, dyp, dz, dE)" msg = msg + os.linesep orbitFinalize(msg) return #--------------------------------------------------------------------- for errCntrl in self.error_controllers: value_tmp = random.gauss(0., value) while (abs(value_tmp) > abs(value) * cut_off_level): value_tmp = random.gauss(0., value) main_rank = 0 value_tmp = orbit_mpi.MPI_Bcast(value_tmp, mpi_datatype.MPI_DOUBLE, main_rank, comm) errCntrl.setDisplacementParameter(key, value_tmp)
def updateErrorParameters(self): """ This is an implementation of parent class abstract method. It updates the error defining parameters for all registered error controllers. """ for errCntrl in self.error_controllers: entr_parent_node = errCntrl.getEntanceNodeParent() exit_parent_node = errCntrl.getExitNodeParent() if (entr_parent_node != exit_parent_node): msg = "Class StraightRotationY_NodesModification update parameters problem!" msg = msg + os.linesep msg = msg + "For this type of Error Node Controllers parent node is one, not two!" msg = msg + os.linesep msg = msg + "Entrance parent node=" + entr_parent_node.getName( ) msg = msg + os.linesep msg = msg + "Exit parent node=" + exit_parent_node.getName( ) msg = msg + os.linesep msg = msg + "Stop" msg = msg + os.linesep orbitFinalize(msg) return errCntrl.setRotationAngle(self.angle) errCntrl.setBaseLength(entr_parent_node.getLength())
def getNodeForName(self,name): """ Method. Returns the node with certain name. """ nodes = [] for node in self.__children: if(node.getName().find(name) == 0): nodes.append(node) if(len(nodes) == 1): return nodes[0] else: if(len(nodes) == 0): return None else: msg = "The AccLattice class. Method getNodeForName found many nodes instead of one!" msg = msg + os.linesep msg = msg + "looking for name="+name msg = msg + os.linesep msg = msg + "found nodes:" for node in nodes: msg = msg + " " + node.getName() msg = msg + os.linesep msg = msg + "Please use getNodesForName method instead." msg = msg + os.linesep orbitFinalize(msg)
def initialize(self): """ The Bend Combined Functions TEAPOT class implementation of the AccNode class initialize() method. """ nParts = self.getnParts() if(nParts < 2): msg = "The Bend Combined Functions TEAPOT class instance should have more than 2 parts!" msg = msg + os.linesep msg = msg + "Method initialize():" msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep msg = msg + "nParts =" + str(nParts) orbitFinalize(msg) rho = self.getLength()/self.getParam("theta") self.addParam("rho",rho) lengthIN = (self.getLength()/(nParts - 1))/2.0 lengthOUT = (self.getLength()/(nParts - 1))/2.0 lengthStep = lengthIN + lengthOUT self.setLength(lengthIN,0) self.setLength(lengthOUT,nParts - 1) for i in xrange(nParts-2): self.setLength(lengthStep,i+1)
def _setPartsLengthEvenly(self, n=1): """ Method. Sets lengths of all parts evenly. """ self.__nParts = n n_body_children = self.getNumberOfBodyChildren() if (n_body_children != 0): msg = "The Class AccNode: method _setPartsLengthEvenly will remove the exiting child nodes!" msg = msg + os.linesep msg = "You will empty self.__childNodesArr[AccNode.BODY] array which is not empty!" msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep msg = msg + "Requested nParts =" + str(n) msg = msg + os.linesep msg = msg + "N body children=" + n_body_children msg = msg + os.linesep orbitFinalize(msg) self.__lengthArr = [] self.__childNodesArr[AccNode.BODY] = [] for i in range(self.__nParts): self.__lengthArr.append(self.__length / self.__nParts) self.__childNodesArr[AccNode.BODY].append([[], []])
def initialize(self): """ The Quad Combined Function class implementation of the AccNode class initialize() method. The parts number should be even to have ability to put correctors at the center of the quad. """ nParts = self.getnParts() if (nParts < 2 and nParts % 2 != 0): msg = "The Quad Combined Function class instance should have no less than 2 and even number of parts!" msg = msg + os.linesep msg = "Even number of parts are needed for the correctors at the center of the quad." msg = msg + os.linesep msg = msg + "Method initialize():" msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep msg = msg + "nParts =" + str(nParts) orbitFinalize(msg) lengthStep = self.getLength() / nParts for i in range(nParts): self.setLength(lengthStep, i) """
def ttf_track_bunch__(self,bunch,frequency,E0L,phase): """ Tracks the bunch through the TTF thin gap model. This private method was introduced to to check the beta TTF limits in the polynomial representation of T,T',S,and S' functions of the relativistic beta. """ beta = bunch.getSyncParticle().beta() beta_min = self.getParam("beta_min") beta_max = self.getParam("beta_max") if(beta < beta_min or beta > beta_max): sequence = self.getSequence() accLattice = sequence.getLinacAccLattice() rfCavity = self.getRF_Cavity() msg = "The Python BaseRF_Gap class. The beta for SyncPart is not in the range [min:max]!" msg = msg + os.linesep if(accLattice != None): msg = msg + "Lattice =" + accLattice.getName() msg = msg + os.linesep if(sequence != None): msg = msg + "Sequence =" + sequence.getName() msg = msg + os.linesep msg = msg + "RF Cavity =" + rfCavity.getName() msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep msg = msg + "beta=" + str(beta) msg = msg + os.linesep msg = msg + "beta min=" + str(beta_min) msg = msg + os.linesep msg = msg + "beta max=" + str(beta_max) msg = msg + os.linesep orbitFinalize(msg) self.cppGapModel.trackBunch(bunch,frequency,E0L,phase,self.polyT,self.polyS,self.polyTp,self.polySp)
def GetEngeFunction(quad): """ This is an example of a EngeFunctionFactory function. It returns the EngeFunction function for the instance of Quad node. The quad should have the aperture parameter. It is used in the quad+rf lattice transformation by default. User can prepare his/her own EngeFunctionFactory function. """ length_param = quad.getLength() if (quad.hasParam("aperture")): acceptance_diameter_param = quad.getParam("aperture") cutoff_level = 0.001 func = EngeFunction(length_param, acceptance_diameter_param, cutoff_level) return func else: msg = "Inside the Replace_BaseRF_Gap_and_Quads_to_Overlapping_Nodes Python function. " msg += os.linesep msg += "Cannot create the EngeFunction for the quad!" msg += os.linesep msg = msg + "quad name = " + quad.getName() msg = msg + os.linesep msg = msg + "It does not have the aperture parameter!" msg = msg + os.linesep orbitFinalize(msg) return None
def ttf_track_bunch__(self,bunch,frequency,E0L,phase): """ Tracks the bunch through the TTF thin gap model. """ beta = bunch.getSyncParticle().beta() beta_min = self.getParam("beta_min") beta_max = self.getParam("beta_max") if(beta < beta_min or beta > beta_max): sequence = self.getSequence() accLattice = sequence.getLinacAccLattice() rfCavity = self.getRF_Cavity() msg = "The Python BaseRF_Gap class. The beta for SyncPart is not in the range [min:max]!" msg = msg + os.linesep if(accLattice != None): msg = msg + "Lattice =" + accLattice.getName() msg = msg + os.linesep if(sequence != None): msg = msg + "Sequence =" + sequence.getName() msg = msg + os.linesep msg = msg + "RF Cavity =" + rfCavity.getName() msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep msg = msg + "beta=" + str(beta) msg = msg + os.linesep msg = msg + "beta min=" + str(beta_min) msg = msg + os.linesep msg = msg + "beta max=" + str(beta_max) msg = msg + os.linesep orbitFinalize(msg) self.cppGapModel.trackBunch(bunch,frequency,E0L,phase,self.polyT,self.polyS,self.polyTp,self.polySp)
def track(self, paramsDict): """ It is tracking the bunch through this node. """ bunch = paramsDict["bunch"] nParts = bunch.getSize() if (nParts < 1): msg = "TransverseBPM class:" msg = msg + os.linesep msg = msg + "Node name=" + self.getName() msg = msg + os.linesep msg = msg + "Number of macro-particles in bunch nParts=" + str( nParts) msg = msg + os.linesep msg = msg + "It should be more than 0" msg = msg + os.linesep msg = msg + "Stop." msg = msg + os.linesep orbitFinalize(msg) elif (nParts > 1): bunch = self.trajCorrection.makeOneParticleBunch(bunch) self.x = bunch.x(0) self.y = bunch.y(0) self.xp = bunch.xp(0) self.yp = bunch.yp(0)
def addNode(self, node): if (not isinstance(node, LinacStuctureNode)): msg = "LinacStructureSeq: cannot add node. It is not LinacStuctureNode instance!" msg = msg + os.linesep msg = msg + "=========================================" msg = msg + os.linesep orbitFinalize(msg) self.nodes.append(node)
def addNode(self,node): if(not isinstance(node,LinacStuctureNode)): msg = "LinacStructureSeq: cannot add node. It is not LinacStuctureNode instance!" msg = msg + os.linesep msg = msg + "=========================================" msg = msg + os.linesep orbitFinalize(msg) self.nodes.append(node)
def track(self, paramsDict): """ The simplest RF gap class implementation of the AccNode class track(probe) method. """ bunch = paramsDict["bunch"] syncPart = bunch.getSyncParticle() E0TL = self.getParam("E0TL") E0L = self.getParam("E0L") modePhase = self.getParam("mode") * math.pi rfCavity = self.getRF_Cavity() frequency = rfCavity.getFrequency() phase = rfCavity.getPhase() + modePhase rf_ampl = rfCavity.getAmp() arrival_time = syncPart.time() designArrivalTime = rfCavity.getDesignArrivalTime() if (self.__isFirstGap): if (rfCavity.isDesignSetUp()): #print "debug RF =",self.getName()," phase=",(phase*180./math.pi - 180.) phase = math.fmod( frequency * (arrival_time - designArrivalTime) * 2.0 * math.pi + phase, 2.0 * math.pi) #print "debug RF =",self.getName()," phase=",(phase*180./math.pi - 180.) else: sequence = self.getSequence() accLattice = sequence.getLinacAccLattice() msg = "The BaseRF_Gap class. You have to run trackDesign on the LinacAccLattice first to initialize all RF Cavities' phases!" msg = msg + os.linesep if (accLattice != None): msg = msg + "Lattice =" + accLattice.getName() msg = msg + os.linesep if (sequence != None): msg = msg + "Sequence =" + sequence.getName() msg = msg + os.linesep msg = msg + "RF Cavity =" + rfCavity.getName() msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep orbitFinalize(msg) else: phase = math.fmod( frequency * (arrival_time - designArrivalTime) * 2.0 * math.pi + phase, 2.0 * math.pi) #---- rf gap input phase ----- self.setGapPhase(phase) #call rf gap model to track the bunch if (rf_ampl == 0.): return if (isinstance(self.cppGapModel, MatrixRfGap) or isinstance(self.cppGapModel, BaseRfGap) or isinstance(self.cppGapModel, BaseRfGap_slow)): self.cppGapModel.trackBunch(bunch, frequency, E0TL * rf_ampl, phase) else: self.ttf_track_bunch__(bunch, frequency, E0L * rf_ampl, phase)
def track(self, paramsDict): """ The simplest RF gap class implementation of the AccNode class track(probe) method. """ index = self.getActivePartIndex() length = self.getLength(index) bunch = paramsDict["bunch"] syncPart = bunch.getSyncParticle() if (index == 0 or index == 2): gapOffset = 0. if (self.hasParam("gapOffset")): gapOffset = self.getParam("gapOffset") if (index == 2): gapOffset = -gapOffset TPB.drift(bunch, length + gapOffset) return E0TL = self.getParam("E0TL") modePhase = self.getParam("modePhase") * math.pi rfCavity = self.getRF_Cavity() frequency = rfCavity.getFrequency() rfPhase = rfCavity.getPhase() + modePhase rf_ampl = rfCavity.getAmp() phase = rfPhase arrival_time = syncPart.time() designArrivalTime = rfCavity.getDesignArrivalTime() if (self.__isFirstGap): if (rfCavity.isDesignSetUp()): #print "debug RF =",self.getName()," phase=",(phase*180./math.pi - 180.) phase = math.fmod( frequency * (arrival_time - designArrivalTime) * 2.0 * math.pi + rfPhase, 2.0 * math.pi) #print "debug RF =",self.getName()," phase=",(phase*180./math.pi - 180.) else: sequence = self.getSequence() accLattice = sequence.getLinacAccLattice() msg = "The BaseRF_Gap class. You have to run trackDesign on the LinacAccLattice first to initialize all RF Cavities' phases!" msg = msg + os.linesep msg = msg + "Lattice =" + accLattice.getName() msg = msg + os.linesep msg = msg + "Sequence =" + sequence.getName() msg = msg + os.linesep msg = msg + "RF Cavity =" + rfCavity.getName() msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep orbitFinalize(msg) else: phase = math.fmod( frequency * (arrival_time - designArrivalTime) * 2.0 * math.pi + rfPhase, 2.0 * math.pi) #------------------------------------------------------ #call rf gap with E0TL phase phase of the gap and a longitudinal shift parameter self.cppGapModel.trackBunch(bunch, frequency, E0TL, phase) self.setGapPhase(phase)
def addTeapotApertureNode(lattice, position, Aperture_node): """ It will put one Teapot Aperture node in the lattice """ length_tolerance = 0.0001 lattice.initialize() if (position > lattice.getLength()): position = lattice.getLength() print "User-specified aperture position is larger than lattice length. Resetting it to lattice length." Aperture_node.setPosition(position) position_start = position position_stop = position + Aperture_node.getLength() (node_start_ind, node_stop_ind, z, ind) = (-1, -1, 0., 0) for node in lattice.getNodes(): if (position_start >= z and position_start <= z + node.getLength()): node_start_ind = ind if (position_stop >= z and position_stop <= z + node.getLength()): node_stop_ind = ind ind += 1 z += node.getLength() #-------now we check that between start and end we have only non-modified drift elements #-------if the space charge was added first - that is a problem. The collimation should be added first. for node in lattice.getNodes()[node_start_ind:node_stop_ind + 1]: #print "debug node=",node.getName()," type=",node.getType()," L=",node.getLength() if (not isinstance(node, DriftTEAPOT)): print "Non-drift node=", node.getName(), " type=", node.getType( ), " L=", node.getLength() orbitFinalize( "We have non-drift element at the place of the Aperture node! Stop!" ) #if(node.getNumberOfChildren() != 4): #print "Node=",node.getName()," type=",node.getType()," L=",node.getLength()," N children nodes=",node.getNumberOfChildren() #orbitFinalize("Drift element was modified with additional functionality (SC or something else)! Add collimation first! Stop!") # make array of nodes from Aperture node in the center and possible two drifts if their length is more than length_tollerance [m] nodes_new_arr = [ Aperture_node, ] drift_node_start = lattice.getNodes()[node_start_ind] drift_node_stop = lattice.getNodes()[node_stop_ind] #------now we will create two drift nodes: before the Aperture node and after #------if the length of one of these additional drifts less than length_tollerance [m] we skip this drift if (position_start > lattice.getNodePositionsDict()[drift_node_start][0] + length_tolerance): drift_node_start_new = DriftTEAPOT(drift_node_start.getName()) drift_node_start_new.setLength( position_start - lattice.getNodePositionsDict()[drift_node_start][0]) nodes_new_arr.insert(0, drift_node_start_new) if (position_stop < lattice.getNodePositionsDict()[drift_node_stop][1] - length_tolerance): drift_node_stop_new = DriftTEAPOT(drift_node_stop.getName()) drift_node_stop_new.setLength( lattice.getNodePositionsDict()[drift_node_stop][1] - position_stop) nodes_new_arr.append(drift_node_stop_new) #------ now we will modify the lattice by replacing the found part with the new nodes lattice.getNodes()[node_start_ind:node_stop_ind + 1] = nodes_new_arr # initialize the lattice lattice.initialize()
def __init__(self, teapot_lattice, bunch, name=None): MATRIX_Lattice.__init__(self, name) if (isinstance(teapot_lattice, TEAPOT_Lattice) != True): orbitFinalize( "Constructor orbit.teapot.TEAPOT_MATRIX_Lattice needs the TEAPOT_Lattice instance." ) #memorize the TEAPOT LATTICE if (name == None): name = teapot_lattice.getName() self.setName(name) self.teapot_lattice = teapot_lattice self.bunch = Bunch() self.lost_bunch = Bunch() bunch.copyEmptyBunchTo(self.bunch) bunch.copyEmptyBunchTo(self.lost_bunch) self.matrixGenerator = MatrixGenerator() #----------make MATRIX lattice from TEAPOT def twissAction(paramsDict): node = paramsDict["node"] bunch = paramsDict["bunch"] active_index = node.getActivePartIndex() n_parts = node.getnParts() length = node.getLength(active_index) if (isinstance(node, BaseTEAPOT) == True and isinstance(node, RingRFTEAPOT) == False): self.matrixGenerator.initBunch(bunch) node.track(paramsDict) #bunch is ready matrixNode = BaseMATRIX(node.getName() + "_" + str(active_index)) matrixNode.addParam("matrix_parent_node", node) matrixNode.addParam("matrix_parent_node_type", node.getType()) matrixNode.addParam("matrix_parent_node_n_nodes", n_parts) matrixNode.addParam("matrix_parent_node_active_index", active_index) matrixNode.setLength(length) self.matrixGenerator.calculateMatrix(bunch, matrixNode.getMatrix()) #print "============= name=",matrixNode.getName(), #print " type=",matrixNode.getParam("matrix_parent_node_type"), #print " L=",matrixNode.getLength() self.addNode(matrixNode) if (isinstance(node, RingRFTEAPOT) == True): rf_node = RingRFTEAPOT(node.getName()) rf_node.setParamsDict(node.getParamsDict().copy()) self.addNode(rf_node) accContainer = AccActionsContainer() accContainer.addAction(twissAction, AccActionsContainer.BODY) paramsDict = {} paramsDict["bunch"] = self.bunch paramsDict["lostbunch"] = self.lost_bunch paramsDict["position"] = 0. paramsDict["useCharge"] = self.teapot_lattice.getUseRealCharge() self.teapot_lattice.trackActions(accContainer, paramsDict) self.makeOneTurnMatrix() self.initialize()
def addSeq(self, node): if (not isinstance(node, LinacStructureSeq)): msg = "LinacStructureTree: cannot add node. It is not LinacStructureSeq instance!" msg = msg + os.linesep msg = msg + "=========================================" msg = msg + os.linesep orbitFinalize(msg) self.seqs.append(node) self.length = self.length + node.getParam("length")
def addSeq(self,node): if(not isinstance(node,LinacStructureSeq)): msg = "LinacStructureTree: cannot add node. It is not LinacStructureSeq instance!" msg = msg + os.linesep msg = msg + "=========================================" msg = msg + os.linesep orbitFinalize(msg) self.seqs.append(node) self.length = self.length + node.getParam("length")
def addRFNode(lattice, position, rf_node): """ This will put one rf cavity node in the lattice """ length_tolerance = 0.0001 lattice.initialize() position_start = position position_stop = position + rf_node.getLength() (node_start_ind, node_stop_ind, z, ind) = (-1, -1, 0., 0) for node in lattice.getNodes(): if(position_start >= z and\ position_start <= z + node.getLength()): node_start_ind = ind if(position_stop >= z and\ position_stop <= z + node.getLength()): node_stop_ind = ind ind += 1 z += node.getLength() #-------Now we check that between start and end #-------we have only non-modified drift elements #-------If the rf was added first - that is a problem. #-------The collimation should be added first. for node in lattice.getNodes()[node_start_ind:node_stop_ind + 1]: #print "debug node = ", node.getName(),\ #" type = ", node.getType()," L = ", node.getLength() if (not isinstance(node, DriftTEAPOT)): print "Non-drift node = ", node.getName(),\ " type = ", node.getType()," L = ", node.getLength() orbitFinalize("We have a non-drift element at the\ location of the rf node! Stop!") # Make array of nodes from rf node in the center and possibly # two drifts if their length is more than length_tollerance [m] nodes_new_arr = [ rf_node, ] drift_node_start = lattice.getNodes()[node_start_ind] drift_node_stop = lattice.getNodes()[node_stop_ind] #-------Now we create two drift nodes surrounding the rf node. #-------If the length of one of these additional drifts is #-------less than length_tollerance [m] we skip this drift if(position_start > lattice.getNodePositionsDict()\ [drift_node_start][0] + length_tolerance): drift_node_start_new = DriftTEAPOT(drift_node_start.getName()) drift_node_start_new.setLength(position_start\ - lattice.getNodePositionsDict()[drift_node_start][0]) nodes_new_arr.insert(0, drift_node_start_new) if(position_stop < lattice.getNodePositionsDict()\ [drift_node_stop][1] - length_tolerance): drift_node_stop_new = DriftTEAPOT(drift_node_stop.getName()) drift_node_stop_new.setLength(lattice.getNodePositionsDict\ ()[drift_node_stop][1] - position_stop) nodes_new_arr.append(drift_node_stop_new) #-------Now modify the lattice by replacing the chosen part #-------by the new nodes lattice.getNodes()[node_start_ind:node_stop_ind + 1] = nodes_new_arr # initialize the lattice lattice.initialize()
def __init__(self, xml_file_name): self.dom_doc = xml.dom.minidom.parse(xml_file_name) if (len(self.dom_doc.childNodes) != 1): msg = "SimplifiedLinacParser: input xml file has a wrong structure!" msg = msg + os.linesep msg = msg + "File: " + xml_file_name msg = msg + os.linesep msg = msg + "=========================================" msg = msg + os.linesep orbitFinalize(msg) self.domLinac = self.dom_doc.childNodes[0] self.linacTree = LinacStructureTree(name=self.domLinac.localName) domSequences = self._stripDOMtoElements(self.domLinac) for domSeq in domSequences: linacSeq = LinacStructureSeq(name=domSeq.localName) #print "debug name=",domSeq.localName seqParamDict = {} for i in range(domSeq.attributes.length): seqParamDict[domSeq.attributes.item( i).name] = domSeq.attributes.item(i).value self._transformDict(seqParamDict) linacSeq.setLength(seqParamDict["length"]) linacSeq.setParam("rfFrequency", seqParamDict["rfFrequency"]) linacSeq.setParam("bpmFrequency", seqParamDict["bpmFrequency"]) domNodes = self._stripDOMtoElements(domSeq) for domNode in domNodes: nNodeParam = domNode.attributes.length paramDict = {} for i in range(nNodeParam): paramDict[domNode.attributes.item( i).name] = domNode.attributes.item(i).value #print "i=",i," name=",domNode.attributes.item(i).name," val=",domNode.attributes.item(i).value #---- add parameters from <parameters> child domNode domParameters = self._stripDOMtoElements(domNode) #print "domNode =",domNode.localName ," domParameters=",domParameters if (len(domParameters) > 1): msg = "SimplifiedLinacParser:more than 1 child in accNode!" msg = msg + os.linesep orbitFinalize(msg) if (len(domParameters) == 1): domParameter = domParameters[0] for i in range(domParameter.attributes.length): paramDict[domParameter.attributes.item( i).name] = domParameter.attributes.item(i).value nodeName = paramDict["name"] #the name is not in the dictionary of parameters del paramDict["name"] linacNode = LinacStuctureNode(name=nodeName) linacNode.setType(type_in=paramDict["type"]) #the type is not in the dictionary of parameters del paramDict["type"] self._transformDict(paramDict) linacNode.setParamsDict(paramDict) linacSeq.addNode(linacNode) self.linacTree.addSeq(linacSeq)
def addRF_Cavity(self, cav): if (isinstance(cav, RF_Cavity) == True): self.__rfCavities.append(cav) else: msg = "The LinacAccLattice, method addRF_Cavity(cav)!" msg = msg + os.linesep msg = msg + "cav is not a subclass of RF_Cavity." msg = msg + os.linesep msg = msg + "Stop." msg = msg + os.linesep orbitFinalize(msg)
def addRF_Cavity(self,cav): if(isinstance(cav, RF_Cavity) == True): self.__rfCavities.append(cav) else: msg = "The LinacAccLattice, method addRF_Cavity(cav)!" msg = msg + os.linesep msg = msg + "cav is not a subclass of RF_Cavity." msg = msg + os.linesep msg = msg + "Stop." msg = msg + os.linesep orbitFinalize(msg)
def addTeapotDiagnosticsNode(lattice, position, diagnostics_node): """ It will put one Teapot diagnostics node in the lattice """ length_tollerance = 0.0001 lattice.initialize() position_start = position position_stop = position + diagnostics_node.getLength() diagnostics_node.setPosition(position) diagnostics_node.setLatticeLength(lattice.getLength()) (node_start_ind, node_stop_ind, z, ind) = (-1, -1, 0., 0) for node in lattice.getNodes(): if (position_start >= z and position_start <= z + node.getLength()): node_start_ind = ind if (position_stop >= z and position_stop <= z + node.getLength()): node_stop_ind = ind ind += 1 z += node.getLength() #-------now we check that between start and end we have only non-modified drift elements #-------if the space charge was added first - that is a problem. The collimation should be added first. for node in lattice.getNodes()[node_start_ind:node_stop_ind + 1]: #print "debug node=",node.getName()," type=",node.getType()," L=",node.getLength() if (not isinstance(node, DriftTEAPOT)): print "Non-drift node=", node.getName(), " type=", node.getType( ), " L=", node.getLength() orbitFinalize( "We have non-drift element at the place of the diagnostics! Stop!" ) # make array of nodes from diagnostics in the center and possible two drifts if their length is more than length_tollerance [m] nodes_new_arr = [ diagnostics_node, ] drift_node_start = lattice.getNodes()[node_start_ind] drift_node_stop = lattice.getNodes()[node_stop_ind] #------now we will create two drift nodes: before the diagnostics and after #------if the length of one of these additional drifts less than length_tollerance [m] we skip this drift if (position_start > lattice.getNodePositionsDict()[drift_node_start][0] + length_tollerance): drift_node_start_new = DriftTEAPOT(drift_node_start.getName()) drift_node_start_new.setLength( position_start - lattice.getNodePositionsDict()[drift_node_start][0]) nodes_new_arr.insert(0, drift_node_start_new) if (position_stop < lattice.getNodePositionsDict()[drift_node_stop][1] - length_tollerance): drift_node_stop_new = DriftTEAPOT(drift_node_stop.getName()) drift_node_stop_new.setLength( lattice.getNodePositionsDict()[drift_node_stop][1] - position_stop) nodes_new_arr.append(drift_node_stop_new) #------ now we will modify the lattice by replacing the found part with the new nodes lattice.getNodes()[node_start_ind:node_stop_ind + 1] = nodes_new_arr # initialize the lattice lattice.initialize()
def addSequence(self,seq): if(isinstance(seq, Sequence) == True): self.__sequences.append(seq) else: msg = "The LinacAccLattice, method addSequence(seq)!" msg = msg + os.linesep msg = msg + "seq is not a subclass of Sequence." msg = msg + os.linesep msg = msg + "Stop." msg = msg + os.linesep orbitFinalize(msg)
def addSequence(self, seq): if (isinstance(seq, Sequence) == True): self.__sequences.append(seq) else: msg = "The LinacAccLattice, method addSequence(seq)!" msg = msg + os.linesep msg = msg + "seq is not a subclass of Sequence." msg = msg + os.linesep msg = msg + "Stop." msg = msg + os.linesep orbitFinalize(msg)
def __init__(self, ltree): if (isinstance(ltree, LinacStructureTree) != True): msg = "The LinacLatticeFactory constructor: you have to specify the LinacStructureTree instance as input!" msg = msg + os.linesep msg = msg + "Stop." msg = msg + os.linesep orbitFinalize(msg) self.ltree = ltree #We need to compare positions, lengths etc. This is our delta self.zeroDistance = 0.00001 #The maximal length of the drift. It will be devided if it is more than that. self.maxDriftLength = 1.
def addRF_Cavity(self, cav): """ Adds the RF cavity to the list inside this sequence. """ if (isinstance(cav, RF_Cavity) == True): self.__rfCavities.append(cav) else: msg = "The Sequence class , method addRF_Cavity(cav)!" msg = msg + os.linesep msg = msg + "cav is not a subclass of RF_Cavity." msg = msg + os.linesep msg = msg + "Stop." msg = msg + os.linesep orbitFinalize(msg)
def setZ_Step(self,z_step): if(self.axis_field_func == None): msg = "Class AxisFieldRF_Gap: You have to get the axis field from a file first!" msg = msg + os.linesep msg = "Call readAxisFieldFile(dir_location,file_name) method first!" orbitFinalize(msg) length = self.getLength() nParts = int(length*1.0000001/z_step) if(nParts < 1): nParts = 1 self.z_step = length/nParts #---- this will set the even distribution of the lengths between parts self.setnParts(nParts)
def __init__(self,xml_file_name): self.dom_doc = xml.dom.minidom.parse(xml_file_name) if(len(self.dom_doc.childNodes) != 1): msg = "SimplifiedLinacParser: input xml file has a wrong structure!" msg = msg + os.linesep msg = msg + "File: " + xml_file_name msg = msg + os.linesep msg = msg + "=========================================" msg = msg + os.linesep orbitFinalize(msg) self.domLinac = self.dom_doc.childNodes[0] self.linacTree = LinacStructureTree(name = self.domLinac.localName) domSequences = self._stripDOMtoElements(self.domLinac) for domSeq in domSequences: linacSeq = LinacStructureSeq(name = domSeq.localName) #print "debug name=",domSeq.localName seqParamDict = {} for i in range(domSeq.attributes.length): seqParamDict[domSeq.attributes.item(i).name] = domSeq.attributes.item(i).value self._transformDict(seqParamDict) linacSeq.setLength(seqParamDict["length"]) linacSeq.setParam("rfFrequency",seqParamDict["rfFrequency"]) linacSeq.setParam("bpmFrequency",seqParamDict["bpmFrequency"]) domNodes = self._stripDOMtoElements(domSeq) for domNode in domNodes: nNodeParam = domNode.attributes.length paramDict = {} for i in range(nNodeParam): paramDict[domNode.attributes.item(i).name] = domNode.attributes.item(i).value #print "i=",i," name=",domNode.attributes.item(i).name," val=",domNode.attributes.item(i).value #---- add parameters from <parameters> child domNode domParameters = self._stripDOMtoElements(domNode) #print "domNode =",domNode.localName ," domParameters=",domParameters if(len(domParameters) > 1): msg = "SimplifiedLinacParser:more than 1 child in accNode!" msg = msg + os.linesep orbitFinalize(msg) if(len(domParameters) == 1): domParameter = domParameters[0] for i in range(domParameter.attributes.length): paramDict[domParameter.attributes.item(i).name] = domParameter.attributes.item(i).value nodeName = paramDict["name"] #the name is not in the dictionary of parameters del paramDict["name"] linacNode = LinacStuctureNode(name = nodeName) linacNode.setType(type_in = paramDict["type"]) #the type is not in the dictionary of parameters del paramDict["type"] self._transformDict(paramDict) linacNode.setParamsDict(paramDict) linacSeq.addNode(linacNode) self.linacTree.addSeq(linacSeq)
def getLinacAccLattice(self,names,xml_file_name): """ Returns the linac accelerator lattice for specified sequence names and for a specified XML file. """ if(len(names) < 1): msg = "The SNS_LinacLatticeFactory method getLinacAccLattice(names,xml_file_name): you have to specify the names array!" msg = msg + os.linesep msg = msg + "Stop." msg = msg + os.linesep orbitFinalize(msg) #----- let's parse the XML file acc_da = XmlDataAdaptor.adaptorForFile(xml_file_name) return self.getLinacAccLatticeFromDA(names,acc_da)
def Get_quads_zeroLengthNodes_in_range(accSeq, node_ind_start, node_ind_end): """ Returns all quads and zero-length nodes in this index range. It also checks that all elements inside this range has zero length or they are drifts of quads. """ nodes = accSeq.getNodes() zero_length_nodes = [] child_nodes = [] quads = [] for node_ind in range(node_ind_start, node_ind_end + 1): node = nodes[node_ind] children_arr = node.getBodyChildren() if (len(children_arr) > 0): #print "debug ========= parent node=",node.getName()," pos = ",node.getPosition() for child in children_arr: if (child.getLength() == 0.): child_nodes.append(child) #print " debug child=",child.getName()," pos=",child.getPosition() if (not isinstance(node, BaseRF_Gap)): length = node.getLength() if (length == 0.): zero_length_nodes.append(node) else: if (isinstance(node, Quad)): quads.append(node) else: if (not isinstance(node, Drift)): msg = "The Replace_BaseRF_Gap_and_Quads_to_Overlapping_Nodes function. " msg += "This Acc. Sequence has an element that " msg += os.linesep msg += "1. has non-zero length" msg += os.linesep msg += "2. not a quad" msg += os.linesep msg += "3. not a drift" msg += os.linesep msg += "This function does not know how to handle this elelement!" msg += os.linesep msg = msg + "Acc Sequence =" + accSeq.getName() msg = msg + os.linesep msg = msg + "Acc element =" + node.getName() msg = msg + os.linesep msg = msg + "Acc element type =" + node.getType() msg = msg + os.linesep orbitFinalize(msg) zero_length_nodes += child_nodes zero_length_nodes = sorted(zero_length_nodes, key=lambda x: x.getPosition(), reverse=False) return (quads, zero_length_nodes)
def track(self, paramsDict): """ The simplest RF gap class implementation of the AccNode class track(probe) method. """ index = self.getActivePartIndex() length = self.getLength(index) bunch = paramsDict["bunch"] syncPart = bunch.getSyncParticle() if(index == 0 or index == 2): gapOffset = 0. if(self.hasParam("gapOffset")): gapOffset = self.getParam("gapOffset") if(index == 2): gapOffset = -gapOffset TPB.drift(bunch, length + gapOffset) return E0TL = self.getParam("E0TL") modePhase = self.getParam("modePhase")*math.pi rfCavity = self.getRF_Cavity() frequency = rfCavity.getFrequency() rfPhase = rfCavity.getPhase() + modePhase rf_ampl = rfCavity.getAmp() phase = rfPhase arrival_time = syncPart.time() designArrivalTime = rfCavity.getDesignArrivalTime() if(self.__isFirstGap): if(rfCavity.isDesignSetUp()): #print "debug RF =",self.getName()," phase=",(phase*180./math.pi - 180.) phase = math.fmod(frequency*(arrival_time - designArrivalTime)*2.0*math.pi + rfPhase,2.0*math.pi) #print "debug RF =",self.getName()," phase=",(phase*180./math.pi - 180.) else: sequence = self.getSequence() accLattice = sequence.getLinacAccLattice() msg = "The BaseRF_Gap class. You have to run trackDesign on the LinacAccLattice first to initialize all RF Cavities' phases!" msg = msg + os.linesep msg = msg + "Lattice =" + accLattice.getName() msg = msg + os.linesep msg = msg + "Sequence =" + sequence.getName() msg = msg + os.linesep msg = msg + "RF Cavity =" + rfCavity.getName() msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep orbitFinalize(msg) else: phase = math.fmod(frequency*(arrival_time - designArrivalTime)*2.0*math.pi+rfPhase,2.0*math.pi) #------------------------------------------------------ #call rf gap with E0TL phase phase of the gap and a longitudinal shift parameter self.cppGapModel.trackBunch(bunch,frequency,E0TL,phase) self.setGapPhase(phase)
def AddBendDisplacementError(self): """ Adds a BendDisplacementError to nodes between nodeIndexi and nodeIndexf. """ lattice = self.lattice lattice.initialize() nodeIndexi = self.nodeIndexi nodeIndexf = self.nodeIndexf Indexf = nodeIndexf + 1 sample = self.localDict["sample"] multfrac = 1.0 if(sample == "Uniform"): minimum = self.localDict["minimum"] maximum = self.localDict["maximum"] multfrac = minimum + (maximum - minimum) * random() if(sample == "Gaussian"): mean = self.localDict["mean"] sigma = self.localDict["sigma"] multfrac = gauss(mean, sigma) disp = self.localDict["disp"] * multfrac theta = 0.0 if(nodeIndexi > nodeIndexf): Indexf = len(lattice.getNodes()) for node in lattice.getNodes()[0 : nodeIndexf + 1]: if(not isinstance(node, BendTEAPOT)): print "Node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Can't add BendError around a Straight! Stop!") else: theta += node.getParam("theta") for node in lattice.getNodes()[nodeIndexi : Indexf]: if(not isinstance(node, BendTEAPOT)): print "Node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Can't add BendError around a Straight! Stop!") else: theta += node.getParam("theta") nodei = lattice.getNodes()[nodeIndexi] nodef = lattice.getNodes()[nodeIndexf] if(self.localDict["subtype"] == "XDisp"): errori = benddisplacementxi(theta, disp) errorf = benddisplacementxf(theta, disp) if(self.localDict["subtype"] == "YDisp"): errori = benddisplacementyi(disp) errorf = benddisplacementyf(disp) if(self.localDict["subtype"] == "LongDisp"): errori = benddisplacementli(theta, disp) errorf = benddisplacementlf(theta, disp) addErrorNodeAsChild_I(lattice, nodei, errori) addErrorNodeAsChild_F(lattice, nodef, errorf)
def __init__(self, teapot_lattice, bunch, name = None): MATRIX_Lattice.__init__(self,name) if(isinstance(teapot_lattice,TEAPOT_Lattice) != True): orbitFinalize("Constructor orbit.teapot.TEAPOT_MATRIX_Lattice needs the TEAPOT_Lattice instance.") #memorize the TEAPOT LATTICE if(name == None): name = teapot_lattice.getName() self.setName(name) self.teapot_lattice = teapot_lattice self.bunch = Bunch() self.lost_bunch = Bunch() bunch.copyEmptyBunchTo(self.bunch) bunch.copyEmptyBunchTo(self.lost_bunch) self.matrixGenerator = MatrixGenerator() #----------make MATRIX lattice from TEAPOT def twissAction(paramsDict): node = paramsDict["node"] bunch = paramsDict["bunch"] active_index = node.getActivePartIndex() n_parts = node.getnParts() length = node.getLength(active_index) if(isinstance(node,BaseTEAPOT) == True and isinstance(node,RingRFTEAPOT) == False): self.matrixGenerator.initBunch(bunch) node.track(paramsDict) #bunch is ready matrixNode = BaseMATRIX(node.getName()+"_"+str(active_index)) matrixNode.addParam("matrix_parent_node",node) matrixNode.addParam("matrix_parent_node_type",node.getType()) matrixNode.addParam("matrix_parent_node_n_nodes",n_parts) matrixNode.addParam("matrix_parent_node_active_index",active_index) matrixNode.setLength(length) self.matrixGenerator.calculateMatrix(bunch,matrixNode.getMatrix()) #print "============= name=",matrixNode.getName(), #print " type=",matrixNode.getParam("matrix_parent_node_type"), #print " L=",matrixNode.getLength() self.addNode(matrixNode) if(isinstance(node,RingRFTEAPOT) == True): rf_node = RingRFTEAPOT(node.getName()) rf_node.setParamsDict(node.getParamsDict().copy()) self.addNode(rf_node) accContainer = AccActionsContainer() accContainer.addAction(twissAction,AccActionsContainer.BODY) paramsDict = {} paramsDict["bunch"] = self.bunch paramsDict["lostbunch"] = self.lost_bunch paramsDict["position"] = 0. paramsDict["useCharge"] = self.teapot_lattice.getUseRealCharge() self.teapot_lattice.trackActions(accContainer,paramsDict) self.makeOneTurnMatrix() self.initialize()
def checkType(self, name_in): """ Method. Confirms validity of element type. """ name = name_in.lower() if (self.__names_type.count(name) == 0): msg = "Error creating lattice element:" msg = msg + os.linesep msg = msg + "There is no element with type:" + name msg = msg + os.linesep msg = msg + "Stop." msg = msg + os.linesep orbitFinalize(msg) return name_in
def track(self, paramsDict): """ The simplest RF gap class implementation of the AccNode class track(probe) method. """ bunch = paramsDict["bunch"] syncPart = bunch.getSyncParticle() E0TL = self.getParam("E0TL") E0L = self.getParam("E0L") modePhase = self.getParam("mode")*math.pi rfCavity = self.getRF_Cavity() frequency = rfCavity.getFrequency() phase = rfCavity.getPhase() + modePhase rf_ampl = rfCavity.getAmp() arrival_time = syncPart.time() designArrivalTime = rfCavity.getDesignArrivalTime() if(self.__isFirstGap): if(rfCavity.isDesignSetUp()): #print "debug RF =",self.getName()," phase=",(phase*180./math.pi - 180.) phase = math.fmod(frequency*(arrival_time - designArrivalTime)*2.0*math.pi + phase,2.0*math.pi) #print "debug RF =",self.getName()," phase=",(phase*180./math.pi - 180.) else: sequence = self.getSequence() accLattice = sequence.getLinacAccLattice() msg = "The BaseRF_Gap class. You have to run trackDesign on the LinacAccLattice first to initialize all RF Cavities' phases!" msg = msg + os.linesep if(accLattice != None): msg = msg + "Lattice =" + accLattice.getName() msg = msg + os.linesep if(sequence != None): msg = msg + "Sequence =" + sequence.getName() msg = msg + os.linesep msg = msg + "RF Cavity =" + rfCavity.getName() msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep orbitFinalize(msg) else: phase = math.fmod(frequency*(arrival_time - designArrivalTime)*2.0*math.pi+phase,2.0*math.pi) #---- rf gap input phase ----- self.setGapPhase(phase) #call rf gap model to track the bunch if(isinstance(self.cppGapModel,MatrixRfGap) or isinstance(self.cppGapModel,BaseRfGap)): self.cppGapModel.trackBunch(bunch,frequency,E0TL*rf_ampl,phase) else: self.ttf_track_bunch__(bunch,frequency,E0L*rf_ampl,phase)
def addTeapotCollimatorNode(lattice, position, collimator_node): """ It will put one Teapot collimation node in the lattice """ length_tolerance = 0.0001 lattice.initialize() if(position > lattice.getLength() ): position = lattice.getLength(); print "User-specified aperture position is larger than lattice length. Resetting it to lattice length." collimator_node.setPosition(position); position_start = position position_stop = position + collimator_node.getLength() (node_start_ind,node_stop_ind,z,ind) = (-1,-1, 0., 0) for node in lattice.getNodes(): if(position_start >= z and position_start <= z + node.getLength()): node_start_ind = ind if(position_stop >= z and position_stop <= z + node.getLength()): node_stop_ind = ind ind += 1 z += node.getLength() #-------now we check that between start and end we have only non-modified drift elements #-------if the space charge was added first - that is a problem. The collimation should be added first. for node in lattice.getNodes()[node_start_ind:node_stop_ind+1]: #print "debug node=",node.getName()," type=",node.getType()," L=",node.getLength() if(not isinstance(node,DriftTEAPOT)): print "Non-drift node=",node.getName()," type=",node.getType()," L=",node.getLength() orbitFinalize("We have non-drift element at the place of the collimator! Stop!") #if(node.getNumberOfChildren() != 4): #print "Node=",node.getName()," type=",node.getType()," L=",node.getLength()," N children nodes=",node.getNumberOfChildren() #orbitFinalize("Drift element was modified with additional functionality (SC or something else)! Add collimation first! Stop!") # make array of nodes from collimator in the center and possible two drifts if their length is more than length_tolerance [m] nodes_new_arr = [collimator_node,] drift_node_start = lattice.getNodes()[node_start_ind] drift_node_stop = lattice.getNodes()[node_stop_ind] #------now we will create two drift nodes: before the collimator and after #------if the length of one of these additional drifts less than length_tollerance [m] we skip this drift if(position_start > lattice.getNodePositionsDict()[drift_node_start][0] + length_tolerance): drift_node_start_new = DriftTEAPOT(drift_node_start.getName()) drift_node_start_new.setLength(position_start - lattice.getNodePositionsDict()[drift_node_start][0]) nodes_new_arr.insert(0,drift_node_start_new) if(position_stop < lattice.getNodePositionsDict()[drift_node_stop][1] - length_tolerance): drift_node_stop_new = DriftTEAPOT(drift_node_stop.getName()) drift_node_stop_new.setLength(lattice.getNodePositionsDict()[drift_node_stop][1] - position_stop) nodes_new_arr.append(drift_node_stop_new) #------ now we will modify the lattice by replacing the found part with the new nodes lattice.getNodes()[node_start_ind:node_stop_ind+1] = nodes_new_arr # initialize the lattice lattice.initialize()
def initialize(self): """ Method. Initializes the lattice and child node structures. """ res_dict = {} for node in self.__children: if(res_dict.has_key(node)): msg = "The AccLattice class instance should not have duplicate nodes!" msg = msg + os.linesep msg = msg + "Method initialize():" msg = msg + os.linesep msg = msg + "Name of node=" + node.getName() msg = msg + os.linesep msg = msg + "Type of node=" + node.getType() msg = msg + os.linesep orbitFinalize(msg) else: res_dict[node] = None node.initialize() del res_dict paramsDict = {} actions = AccActionsContainer() d = [0.] posn = {} def accNodeExitAction(paramsDict): """ Nonbound function. Sets lattice length and node positions. This is a closure (well, maybe not exactly). It uses external objects. """ node = paramsDict["node"] parentNode = paramsDict["parentNode"] if(isinstance(parentNode, AccLattice)): posBefore = d[0] d[0] += node.getLength() posAfter = d[0] posn[node]=(posBefore, posAfter) actions.addAction(accNodeExitAction, AccNode.EXIT) self.trackActions(actions, paramsDict) self.__length = d[0] self.__childPositions = posn self.__isInitialized = True
def addTeapotDiagnosticsNode(lattice, position, diagnostics_node): """ It will put one Teapot diagnostics node in the lattice """ length_tollerance = 0.0001 lattice.initialize() position_start = position position_stop = position + diagnostics_node.getLength() diagnostics_node.setPosition(position) diagnostics_node.setLatticeLength(lattice.getLength()) (node_start_ind,node_stop_ind,z,ind) = (-1,-1, 0., 0) for node in lattice.getNodes(): if(position_start >= z and position_start <= z + node.getLength()): node_start_ind = ind if(position_stop >= z and position_stop <= z + node.getLength()): node_stop_ind = ind ind += 1 z += node.getLength() #-------now we check that between start and end we have only non-modified drift elements #-------if the space charge was added first - that is a problem. The collimation should be added first. for node in lattice.getNodes()[node_start_ind:node_stop_ind+1]: #print "debug node=",node.getName()," type=",node.getType()," L=",node.getLength() if(not isinstance(node,DriftTEAPOT)): print "Non-drift node=",node.getName()," type=",node.getType()," L=",node.getLength() orbitFinalize("We have non-drift element at the place of the diagnostics! Stop!") # make array of nodes from diagnostics in the center and possible two drifts if their length is more than length_tollerance [m] nodes_new_arr = [diagnostics_node,] drift_node_start = lattice.getNodes()[node_start_ind] drift_node_stop = lattice.getNodes()[node_stop_ind] #------now we will create two drift nodes: before the diagnostics and after #------if the length of one of these additional drifts less than length_tollerance [m] we skip this drift if(position_start > lattice.getNodePositionsDict()[drift_node_start][0] + length_tollerance): drift_node_start_new = DriftTEAPOT(drift_node_start.getName()) drift_node_start_new.setLength(position_start - lattice.getNodePositionsDict()[drift_node_start][0]) nodes_new_arr.insert(0,drift_node_start_new) if(position_stop < lattice.getNodePositionsDict()[drift_node_stop][1] - length_tollerance): drift_node_stop_new = DriftTEAPOT(drift_node_stop.getName()) drift_node_stop_new.setLength(lattice.getNodePositionsDict()[drift_node_stop][1] - position_stop) nodes_new_arr.append(drift_node_stop_new) #------ now we will modify the lattice by replacing the found part with the new nodes lattice.getNodes()[node_start_ind:node_stop_ind+1] = nodes_new_arr # initialize the lattice lattice.initialize()
def initialize(self): """ The Ring RF TEAPOT class implementation of the AccNode class initialize() method. """ nParts = self.getnParts() if(nParts > 1): msg = "The Ring RF TEAPOT class instance should not have more than 1 part!" msg = msg + os.linesep msg = msg + "Method initialize():" msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep msg = msg + "nParts =" + str(nParts) msg = msg + os.linesep msg = msg + "length =" + str(self.getLength()) orbitFinalize(msg)
def setnParts(self, n = 1): """ Method. Sets the number of body parts of the node. """ if(self.getNumberOfBodyChildren() != 0): msg = "You cannot set the number of AccNode parts after you added children! Class AccNode" msg = msg + os.linesep msg = msg + "Method setnParts(n):" msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep msg = msg + "nParts =" + str(n) msg = msg + os.linesep msg = msg + "n children =" + str(self.getNumberOfChildren()) orbitFinalize(msg) self._setPartsLengthEvenly(n) self.initialize()
def initialize(self): """ The Ring RF TEAPOT class implementation of the AccNode class initialize() method. """ nParts = self.getnParts() if(nParts != 1): msg = "The simple Rf gap should have 1 parts!" msg = msg + os.linesep msg = msg + "Method initialize():" msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep msg = msg + "nParts =" + str(nParts) msg = msg + os.linesep msg = msg + "lenght =" + str(self.getLength()) orbitFinalize(msg) self.setLength(0.,0)
def rebuild(self, Ekin = -1.0): if(Ekin > 0.): self.bunch.getSyncParticle().kinEnergy(Ekin) for matrixNode in self.getNodes(): if(isinstance(matrixNode,BaseMATRIX) == True): node = matrixNode.getParam("matrix_parent_node") active_index = matrixNode.getParam("matrix_parent_node_active_index") n_parts = matrixNode.getParam("matrix_parent_node_n_nodes") if(n_parts != node.getnParts()): msg = " orbit.teapot.TEAPOT_MATRIX_Lattice class" + os.linesep msg = msg + " rebuild(Ekin = -1.0) method" + os.linesep msg = msg + " TEAPOT node="+node.getName() + os.linesep msg = msg + " has been changed!" + os.linesep msg = msg + " Stop!" + os.linesep orbitFinalize(msg) self.matrixGenerator.initBunch(self.bunch) paramsDict = {} paramsDict["bunch"] = self.bunch paramsDict["node"] = node node.setActivePartIndex(active_index) node.track(paramsDict) self.matrixGenerator.calculateMatrix(self.bunch,matrixNode.getMatrix()) self.makeOneTurnMatrix()
def initialize(self): """ The Quad Combined Function class implementation of the AccNode class initialize() method. """ nParts = self.getnParts() if(nParts < 2 and nParts%2 != 0): msg = "The Quad Combined Function class instance should have no less than 2 and even number of parts!" msg = msg + os.linesep msg = msg + "Method initialize():" msg = msg + os.linesep msg = msg + "Name of element=" + self.getName() msg = msg + os.linesep msg = msg + "Type of element=" + self.getType() msg = msg + os.linesep msg = msg + "nParts =" + str(nParts) orbitFinalize(msg) lengthIN = (self.getLength()/(nParts - 1))/2.0 lengthOUT = (self.getLength()/(nParts - 1))/2.0 lengthStep = lengthIN + lengthOUT self.setLength(lengthIN,0) self.setLength(lengthOUT,nParts - 1) for i in xrange(nParts-2): self.setLength(lengthStep,i+1)
def AddFieldError(self): """ Adds a FieldError to nodes at nodeIndexi to nodeIndexf """ lattice = self.lattice lattice.initialize() nodeIndexi = self.nodeIndexi nodeIndexf = self.nodeIndexf Indexf = nodeIndexf + 1 if(nodeIndexi > nodeIndexf): Indexf = len(lattice.getNodes()) sample = self.localDict["sample"] multfrac = 1.0 if(sample == "Uniform"): minimum = self.localDict["minimum"] maximum = self.localDict["maximum"] multfrac = minimum + (maximum - minimum) * random() if(sample == "Gaussian"): mean = self.localDict["mean"] sigma = self.localDict["sigma"] multfrac = gauss(mean, sigma) fracerr = self.localDict["fracerr"] * multfrac if(self.localDict["subtype"] == "KickField"): if(nodeIndexi > nodeIndexf): for node in lattice.getNodes()[0 : nodeIndexf + 1]: if(not isinstance(node, KickTEAPOT)): print "node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Field Error: Wanted a Kick node! Stop!") kx = node.getParam("kx") * (1.0 + fracerr) ky = node.getParam("ky") * (1.0 + fracerr) node.setParam("kx", kx) node.setParam("ky", ky) for node in lattice.getNodes()[nodeIndexi : Indexf]: if(not isinstance(node, KickTEAPOT)): print "node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Field Error: Wanted a Kick node! Stop!") kx = node.getParam("kx") * (1.0 + fracerr) ky = node.getParam("ky") * (1.0 + fracerr) node.setParam("kx", kx) node.setParam("ky", ky) if(self.localDict["subtype"] == "SolenoidField"): if(nodeIndexi > nodeIndexf): for node in lattice.getNodes()[0 : nodeIndexf + 1]: if(not isinstance(node, SolenoidTEAPOT)): print "node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Field Error: Wanted a Solenoid node! Stop!") B = node.getParam("B") * (1.0 + fracerr) node.setParam("B", B) for node in lattice.getNodes()[nodeIndexi : Indexf]: if(not isinstance(node, SolenoidTEAPOT)): print "node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Field Error: Wanted a Solenoid node! Stop!") B = node.getParam("B") * (1.0 + fracerr) node.setParam("B", B) if(self.localDict["subtype"] == "MultipoleField"): if(nodeIndexi > nodeIndexf): for node in lattice.getNodes()[0 : nodeIndexf + 1]: if(not isinstance(node, MultipoleTEAPOT)): print "node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Field Error: Wanted a Multipole node! Stop!") klArr = node.getParam("kls") for i in xrange(len(klArr)): klArr[i] *= (1.0 + fracerr) node.setParam("kls", klArr) for node in lattice.getNodes()[nodeIndexi : Indexf]: if(not isinstance(node, MultipoleTEAPOT)): print "node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Field Error: Wanted a Multipole node! Stop!") klArr = node.getParam("kls") for i in xrange(len(klArr)): klArr[i] *= (1.0 + fracerr) node.setParam("kls", klArr) if(self.localDict["subtype"] == "QuadField"): if(nodeIndexi > nodeIndexf): for node in lattice.getNodes()[0 : nodeIndexf + 1]: if(not isinstance(node, QuadTEAPOT)): print "node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Field Error: Wanted a Quadrupole node! Stop!") kq = node.getParam("kq") * (1.0 + fracerr) node.setParam("kq", kq) klArr = node.getParam("kls") for i in xrange(len(klArr)): klArr[i] *= (1.0 + fracerr) node.setParam("kls", klArr) for node in lattice.getNodes()[nodeIndexi : Indexf]: if(not isinstance(node, QuadTEAPOT)): print "node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Field Error: Wanted a Quadrupole node! Stop!") kq = node.getParam("kq") * (1.0 + fracerr) node.setParam("kq", kq) klArr = node.getParam("kls") for i in xrange(len(klArr)): klArr[i] *= (1.0 + fracerr) node.setParam("kls", klArr) if(self.localDict["subtype"] == "BendField"): if(nodeIndexi > nodeIndexf): for node in lattice.getNodes()[0 : nodeIndexf + 1]: if(not isinstance(node, BendTEAPOT)): print "node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Field Error: Wanted a Bend node! Stop!") klArr = node.getParam("kls") for i in xrange(len(klArr)): klArr[i] *= (1.0 + fracerr) node.setParam("kls", klArr) for node in lattice.getNodes()[nodeIndexi : Indexf]: if(not isinstance(node, BendTEAPOT)): print "node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Field Error: Wanted a Bend node! Stop!") klArr = node.getParam("kls") for i in xrange(len(klArr)): klArr[i] *= (1.0 + fracerr) node.setParam("kls", klArr) nodei = lattice.getNodes()[nodeIndexi] nodef = lattice.getNodes()[nodeIndexf] drhoi = -nodei.getParam("rho") * fracerr / (1.0 + fracerr) drhof = -nodef.getParam("rho") * fracerr / (1.0 + fracerr) errori = bendfieldi(drhoi) errorf = bendfieldf(drhof) addErrorNodeAsChild_I(lattice, nodei, errori) addErrorNodeAsChild_F(lattice, nodef, errorf)
def AddStraightError(self): """ Adds a StraightError to nodes between nodeIndexi and nodeIndexf. """ lattice = self.lattice lattice.initialize() nodeIndexi = self.nodeIndexi nodeIndexf = self.nodeIndexf Indexf = nodeIndexf + 1 if(nodeIndexi > nodeIndexf): Indexf = len(lattice.getNodes()) for node in lattice.getNodes()[0 : nodeIndexf + 1]: if(isinstance(node, BendTEAPOT)): print "Bend node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Can't add StraightError around a Bend! Stop!") for node in lattice.getNodes()[nodeIndexi : Indexf]: if(isinstance(node, BendTEAPOT)): print "Bend node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Can't add StraightError around a Bend! Stop!") nodei = lattice.getNodes()[nodeIndexi] nodef = lattice.getNodes()[nodeIndexf] sample = self.localDict["sample"] if(self.localDict["subtype"] == "TransDisp"): multdx = 1.0 multdy = 1.0 if(sample == "Uniform"): minimum = self.localDict["minimum"] maximum = self.localDict["maximum"] multdx = minimum + (maximum - minimum) * random() multdy = minimum + (maximum - minimum) * random() if(sample == "Gaussian"): mean = self.localDict["mean"] sigma = self.localDict["sigma"] multdx = gauss(mean, sigma) multdy = gauss(mean, sigma) dx = self.localDict["dx"] * multdx dy = self.localDict["dy"] * multdy errori = coorddisplacement( dx, 0.0, dy, 0.0, 0.0, 0.0) errorf = coorddisplacement(-dx, 0.0, -dy, 0.0, 0.0, 0.0) if(self.localDict["subtype"] == "LongDisp"): multds = 1.0 if(sample == "Uniform"): minimum = self.localDict["minimum"] maximum = self.localDict["maximum"] multds = minimum + (maximum - minimum) * random() if(sample == "Gaussian"): mean = self.localDict["mean"] sigma = self.localDict["sigma"] multds = gauss(mean, sigma) ds = self.localDict["ds"] * multds errori = longdisplacement(ds) errorf = longdisplacement(-ds) if(self.localDict["subtype"] == "XYRot"): multangle = 1.0 if(sample == "Uniform"): minimum = self.localDict["minimum"] maximum = self.localDict["maximum"] multangle = minimum + (maximum - minimum) * random() if(sample == "Gaussian"): mean = self.localDict["mean"] sigma = self.localDict["sigma"] multangle = gauss(mean, sigma) angle = self.localDict["angle"] * multangle errori = straightrotationxy( angle) errorf = straightrotationxy(-angle) if(self.localDict["subtype"] == "XSRot"): multangle = 1.0 if(sample == "Uniform"): minimum = self.localDict["minimum"] maximum = self.localDict["maximum"] multangle = minimum + (maximum - minimum) * random() if(sample == "Gaussian"): mean = self.localDict["mean"] sigma = self.localDict["sigma"] multangle = gauss(mean, sigma) angle = self.localDict["angle"] * multangle if(self.zf >= self.zi): lengtherr = self.zf - self.zi else: lengtherr = lattice.getLength() - self.zf + self.zi errori = straightrotationxsi(angle, lengtherr) errorf = straightrotationxsf(angle, lengtherr) if(self.localDict["subtype"] == "YSRot"): multangle = 1.0 if(sample == "Uniform"): minimum = self.localDict["minimum"] maximum = self.localDict["maximum"] multangle = minimum + (maximum - minimum) * random() if(sample == "Gaussian"): mean = self.localDict["mean"] sigma = self.localDict["sigma"] multangle = gauss(mean, sigma) angle = self.localDict["angle"] * multangle if(self.zf >= self.zi): lengtherr = self.zf - self.zi else: lengtherr = lattice.getLength() - self.zf + self.zi errori = straightrotationysi(angle, lengtherr) errorf = straightrotationysf(angle, lengtherr) addErrorNodeAsChild_I(lattice, nodei, errori) addErrorNodeAsChild_F(lattice, nodef, errorf)
def getLinacAccLatticeFromDA(self,names,acc_da): """ Returns the linac accelerator lattice for specified sequence names. """ if(len(names) < 1): msg = "The SNS_LinacLatticeFactory method getLinacAccLatticeFromDA(names,): you have to specify the names array!" msg = msg + os.linesep msg = msg + "Stop." msg = msg + os.linesep orbitFinalize(msg) #----- let's parse the XML DataAdaptor accSeq_da_arr = acc_da.childAdaptors() #let's check that the names in good order ==start== seqencesLocal = accSeq_da_arr seqencesLocalNames = [] for seq_da in seqencesLocal: seqencesLocalNames.append(seq_da.getName()) ind_old = -1 count = 0 for name in names: ind = seqencesLocalNames.index(name) if(ind < 0 or (count > 0 and ind != (ind_old + 1))): msg = "The LinacLatticeFactory method getLinacAccLattice(names): sequence names array is wrong!" msg = msg + os.linesep msg = msg + "existing names=" + str(seqencesLocalNames) msg = msg + os.linesep msg = msg + "sequence names="+str(names) orbitFinalize(msg) ind_old = ind count += 1 # let's check that the names in good order ==stop== ind_start = seqencesLocalNames.index(names[0]) accSeq_da_arr = accSeq_da_arr[ind_start:ind_start+len(names)] #----make linac lattice linacAccLattice = LinacAccLattice(acc_da.getName()) #There are the folowing possible types of elements in the linac tree: #QUAD - quadrupole #RFGAP - RF Gap #DCH - horizontal dipole corrector #DCV - vertical dipole corrector #Marker - anything else with the length equals to 0 #Before putting enerything into the linacAccLattice we will create sequences # with all nodes. #---------------------------------------------------------------------- # The DRIFTS will be generated additionally and put into right places #---------------------------------------------------------------------- def positionComp(node1_da,node2_da): if(node1_da.getParam("pos") > node2_da.getParam("pos")): return 1 else: if(node1_da.getParam("pos") == node2_da.getParam("pos")): return 0 return -1 accSeqs = [] accRF_Cavs = [] seqPosition = 0. for seq_da in accSeq_da_arr: #print "debug === seq=",seq_da.getName() accSeq = Sequence(seq_da.getName()) accSeq.setLinacAccLattice(linacAccLattice) accSeq.setLength(seq_da.doubleValue("length")) accSeq.setPosition(seqPosition) seqPosition = seqPosition + accSeq.getLength() accSeqs.append(accSeq) #---- BPM frequnecy for this sequence bpmFrequency = seq_da.doubleValue("bpmFrequency") #---- create RF Cavities if(len(seq_da.childAdaptors("Cavities")) == 1): cavs_da = seq_da.childAdaptors("Cavities")[0] cav_da_arr = cavs_da.childAdaptors("Cavity") for cav_da in cav_da_arr: frequency = cav_da.doubleValue("frequency") cav_amp = cav_da.doubleValue("ampl") cav_name = cav_da.stringValue("name") cav_pos = cav_da.doubleValue("pos") cav = RF_Cavity(cav_name) cav.setAmp(cav_amp) cav.setFrequency(frequency) cav.setPosition(cav_pos) accSeq.addRF_Cavity(cav) #---------------------------- #node_da_arr - array of nodes. These nodes are not AccNodes. They are XmlDataAdaptor class instances node_da_arr = seq_da.childAdaptors("accElement") #put nodes in order according to the position in the sequence for node_da in node_da_arr: node_da.setParam("pos",node_da.doubleValue("pos")) node_da_arr.sort(positionComp) #thinNodes - array of accNode nodes with zero length #They can be positioned inside the thick nodes, and this will be done at the end #of this method thinNodes = [] for node_da in node_da_arr: params_da = node_da.childAdaptors("parameters")[0] node_type = node_da.stringValue("type") node_length = node_da.doubleValue("length") node_pos = node_da.getParam("pos") #------------QUAD----------------- if(node_type == "QUAD"): accNode = Quad(node_da.stringValue("name")) accNode.setParam("dB/dr",params_da.doubleValue("field")) accNode.setParam("field",params_da.doubleValue("field")) accNode.setLength(params_da.doubleValue("effLength")) if(params_da.hasAttribute("poles")): accNode.setParam("poles",[int(x) for x in eval(params_da.stringValue("poles"))]) if(params_da.hasAttribute("kls")): accNode.setParam("kls", [x for x in eval(params_da.stringValue("kls"))]) if(params_da.hasAttribute("skews")): accNode.setParam("skews",[int(x) for x in eval(params_da.stringValue("skews"))]) if(0.5*accNode.getLength() > self.maxDriftLength): accNode.setnParts(2*int(0.5*accNode.getLength()/self.maxDriftLength + 1.5 - 1.0e-12)) accNode.setParam("pos",node_pos) if(params_da.hasAttribute("aperture") and params_da.hasAttribute("aprt_type")): accNode.setParam("aprt_type",params_da.intValue("aprt_type")) accNode.setParam("aperture",params_da.doubleValue("aperture")) accSeq.addNode(accNode) #------------BEND----------------- elif(node_type == "BEND"): accNode = Bend(node_da.stringValue("name")) if(params_da.hasAttribute("poles")): accNode.setParam("poles",[int(x) for x in eval(params_da.stringValue("poles"))]) if(params_da.hasAttribute("kls")): accNode.setParam("kls", [x for x in eval(params_da.stringValue("kls"))]) if(params_da.hasAttribute("skews")): accNode.setParam("skews",[int(x) for x in eval(params_da.stringValue("skews"))]) accNode.setParam("ea1",params_da.doubleValue("ea1")) accNode.setParam("ea2",params_da.doubleValue("ea2")) accNode.setParam("theta",params_da.doubleValue("theta")) accNode.setLength(params_da.doubleValue("effLength")) if(0.5*accNode.getLength() > self.maxDriftLength): accNode.setnParts(2*int(0.5*accNode.getLength()/self.maxDriftLength + 1.5 - 1.0e-12)) accNode.setParam("pos",node_pos) accSeq.addNode(accNode) #------------RF_Gap----------------- elif(node_type == "RFGAP"): accNode = BaseRF_Gap(node_da.stringValue("name")) accNode.setLength(0.) accNode.setParam("E0TL",params_da.doubleValue("E0TL")) accNode.setParam("E0L",params_da.doubleValue("E0L")) accNode.setParam("mode",params_da.doubleValue("mode")) accNode.setParam("gap_phase",params_da.doubleValue("phase")*math.pi/180.) accNode.setParam("EzFile",params_da.stringValue("EzFile")) cav_name = params_da.stringValue("cavity") cav = accSeq.getRF_Cavity(cav_name) cav.addRF_GapNode(accNode) if(accNode.isFirstRFGap()): cav.setPhase(accNode.getParam("gap_phase")) #---- TTFs parameters ttfs_da = node_da.childAdaptors("TTFs")[0] accNode.setParam("beta_min",ttfs_da.doubleValue("beta_min")) accNode.setParam("beta_max",ttfs_da.doubleValue("beta_max")) (polyT,polyS,polyTp,polySp) = accNode.getTTF_Polynimials() polyT_da = ttfs_da.childAdaptors("polyT")[0] polyS_da = ttfs_da.childAdaptors("polyS")[0] polyTp_da = ttfs_da.childAdaptors("polyTP")[0] polySp_da = ttfs_da.childAdaptors("polySP")[0] polyT.order(polyT_da.intValue("order")) polyS.order(polyS_da.intValue("order")) polyTp.order(polyTp_da.intValue("order")) polySp.order(polySp_da.intValue("order")) coef_arr = polyT_da.doubleArrayValue("pcoefs") for coef_ind in range(len(coef_arr)): polyT.coefficient(coef_ind,coef_arr[coef_ind]) coef_arr = polyS_da.doubleArrayValue("pcoefs") for coef_ind in range(len(coef_arr)): polyS.coefficient(coef_ind,coef_arr[coef_ind]) coef_arr = polyTp_da.doubleArrayValue("pcoefs") for coef_ind in range(len(coef_arr)): polyTp.coefficient(coef_ind,coef_arr[coef_ind]) coef_arr = polySp_da.doubleArrayValue("pcoefs") for coef_ind in range(len(coef_arr)): polySp.coefficient(coef_ind,coef_arr[coef_ind]) accNode.setParam("pos",node_pos) accSeq.addNode(accNode) else: if(node_length != 0.): msg = "The LinacLatticeFactory method getLinacAccLattice(names): there is a strange element!" msg = msg + os.linesep msg = msg + "name=" + node_da.stringValue("name") msg = msg + os.linesep msg = msg + "type="+node_type msg = msg + os.linesep msg = msg + "length(should be 0.)="+str(node_length) orbitFinalize(msg) #------ thin nodes analysis accNode = None if(node_type == "DCV" or node_type == "DCH"): if(node_type == "DCV"): accNode = DCorrectorV(node_da.stringValue("name")) if(node_type == "DCH"): accNode = DCorrectorH(node_da.stringValue("name")) accNode.setParam("effLength",params_da.doubleValue("effLength")) else: accNode = MarkerLinacNode(node_da.stringValue("name")) accNode.setParam("pos",node_pos) thinNodes.append(accNode) #----- assign the thin nodes that are inside the thick nodes unusedThinNodes = [] for thinNode in thinNodes: thinNode_pos = thinNode.getParam("pos") isInside = False for accNode in accSeq.getNodes(): length = accNode.getLength() if(length > 0.): pos = accNode.getParam("pos") if(thinNode_pos >= (pos-length/2) and thinNode_pos <= (pos+length/2)): isInside = True delta_pos = thinNode_pos - (pos-length/2) s_path = 0. part_ind_in = -1 for part_ind in range(accNode.getnParts()): part_ind_in = part_ind s_path += accNode.getLength(part_ind) if(delta_pos <= s_path + self.zeroDistance): break accNode.addChildNode(thinNode, place = AccNode.BODY, part_index = part_ind_in , place_in_part = AccNode.AFTER) thinNode.setParam("pos",(pos-length/2)+s_path) if(not isInside): unusedThinNodes.append(thinNode) thinNodes = unusedThinNodes newAccNodes = accSeq.getNodes()[:] + thinNodes newAccNodes.sort(positionComp) accSeq.setNodes(newAccNodes) #insert the drifts ======================start =========================== #-----now check the integrety quads and rf_gaps should not overlap #-----and create drifts copyAccNodes = accSeq.getNodes()[:] firstNode = copyAccNodes[0] lastNode = copyAccNodes[len(copyAccNodes)-1] driftNodes_before = [] driftNodes_after = [] #insert the drift before the first element if its half length less than its position if(math.fabs(firstNode.getLength()/2.0 - firstNode.getParam("pos")) > self.zeroDistance): if(firstNode.getLength()/2.0 > firstNode.getParam("pos")): msg = "The LinacLatticeFactory method getLinacAccLattice(names): the first node is too long!" msg = msg + os.linesep msg = msg + "name=" + firstNode.getName() msg = msg + os.linesep msg = msg + "type=" + firstNode.getType() msg = msg + os.linesep msg = msg + "length=" + str(firstNode.getLength()) msg = msg + os.linesep msg = msg + "pos=" + str(firstNode.getParam("pos")) orbitFinalize(msg) else: driftNodes = [] driftLength = firstNode.getParam("pos") - firstNode.getLength()/2.0 nDrifts = int(driftLength/self.maxDriftLength) + 1 driftLength = driftLength/nDrifts for idrift in range(nDrifts): drift = Drift(accSeq.getName()+":"+firstNode.getName()+":"+str(idrift+1)+":drift") drift.setLength(driftLength) drift.setParam("pos",0.+drift.getLength()*(idrift+0.5)) driftNodes.append(drift) driftNodes_before = driftNodes #insert the drift after the last element if its half length less + position is less then the sequence length if(math.fabs(lastNode.getLength()/2.0 + lastNode.getParam("pos") - accSeq.getLength()) > self.zeroDistance): if(lastNode.getLength()/2.0 + lastNode.getParam("pos") > accSeq.getLength()): msg = "The LinacLatticeFactory method getLinacAccLattice(names): the last node is too long!" msg = msg + os.linesep msg = msg + "name=" + lastNode.getName() msg = msg + os.linesep msg = msg + "type=" + lastNode.getType() msg = msg + os.linesep msg = msg + "length=" + str(lastNode.getLength()) msg = msg + os.linesep msg = msg + "pos=" + str(lastNode.getParam("pos")) msg = msg + os.linesep msg = msg + "sequence name=" + accSeq.getName() msg = msg + os.linesep msg = msg + "sequence length=" + str(accSeq.getLength()) orbitFinalize(msg) else: driftNodes = [] driftLength = accSeq.getLength() - (lastNode.getParam("pos") + lastNode.getLength()/2.0) nDrifts = int(driftLength/self.maxDriftLength) + 1 driftLength = driftLength/nDrifts for idrift in range(nDrifts): drift = Drift(accSeq.getName()+":"+lastNode.getName()+":"+str(idrift+1)+":drift") drift.setLength(driftLength) drift.setParam("pos",lastNode.getParam("pos")+lastNode.getLength()/2.0 + drift.getLength()*(idrift+0.5)) driftNodes.append(drift) driftNodes_after = driftNodes #now move on and generate drifts between (i,i+1) nodes from copyAccNodes newAccNodes = driftNodes_before for node_ind in range(len(copyAccNodes)-1): accNode0 = copyAccNodes[node_ind] newAccNodes.append(accNode0) accNode1 = copyAccNodes[node_ind+1] dist = accNode1.getParam("pos") - accNode1.getLength()/2 - (accNode0.getParam("pos") + accNode0.getLength()/2) if(dist < 0.): msg = "The LinacLatticeFactory method getLinacAccLattice(names): two nodes are overlapping!" msg = msg + os.linesep msg = msg + "sequence name=" + accSeq.getName() msg = msg + os.linesep msg = msg + "node 0 name=" + accNode0.getName() + " pos="+ str(accNode0.getParam("pos")) + " L="+str(accNode0.getLength()) msg = msg + os.linesep msg = msg + "node 1 name=" + accNode1.getName() + " pos="+ str(accNode1.getParam("pos")) + " L="+str(accNode1.getLength()) msg = msg + os.linesep orbitFinalize(msg) elif(dist > self.zeroDistance): driftNodes = [] nDrifts = int(dist/self.maxDriftLength) + 1 driftLength = dist/nDrifts for idrift in range(nDrifts): drift = Drift(accSeq.getName()+":"+accNode0.getName()+":"+str(idrift+1)+":drift") drift.setLength(driftLength) drift.setParam("pos",accNode0.getParam("pos")+accNode0.getLength()*0.5+drift.getLength()*(idrift+0.5)) driftNodes.append(drift) newAccNodes += driftNodes else: pass newAccNodes.append(lastNode) newAccNodes += driftNodes_after accSeq.setNodes(newAccNodes) #insert the drifts ======================stop =========================== #add all AccNodes to the linac lattice for accNode in accSeq.getNodes(): linacAccLattice.addNode(accNode) #------- finalize the lattice construction linacAccLattice.initialize() return linacAccLattice
def AddRotationError(self): """ Adds a RotationError to nodes between nodeIndexi and nodeIndexf. """ lattice = self.lattice lattice.initialize() nodeIndexi = self.nodeIndexi nodeIndexf = self.nodeIndexf Indexf = nodeIndexf + 1 sample = self.localDict["sample"] multfrac = 1.0 if(sample == "Uniform"): minimum = self.localDict["minimum"] maximum = self.localDict["maximum"] multfrac = minimum + (maximum - minimum) * random() if(sample == "Gaussian"): mean = self.localDict["mean"] sigma = self.localDict["sigma"] multfrac = gauss(mean, sigma) angle = self.localDict["angle"] * multfrac #print "multfrac, angle = ", multfrac, angle rhoi = 0.0 theta = 0.0 if(self.zf >= self.zi): lengtherr = self.zf - self.zi else: lengtherr = lattice.getLength() - self.zf + self.zi et = self.localDict["elementtype"] rotype = self.localDict["subtype"] if((et == "SBEN") or (et == "sbend") or (et == "rbend")): if(nodeIndexi > nodeIndexf): Indexf = len(lattice.getNodes()) for node in lattice.getNodes()[0 : nodeIndexf + 1]: if(not isinstance(node, BendTEAPOT)): print "Node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Can't add BendError around a Straight! Stop!") else: rhoi = 1.0 / node.getParam("rho") theta += node.getParam("theta") for node in lattice.getNodes()[nodeIndexi : Indexf]: if(not isinstance(node, BendTEAPOT)): print "Node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Can't add BendError around a Straight! Stop!") else: rhoi = 1.0 / node.getParam("rho") theta += node.getParam("theta") else: if(nodeIndexi > nodeIndexf): Indexf = len(lattice.getNodes()) for node in lattice.getNodes()[0 : nodeIndexf + 1]: if(isinstance(node, BendTEAPOT)): print "Node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Can't add StraigtError around a Bend! Stop!") for node in lattice.getNodes()[nodeIndexi : Indexf]: if(isinstance(node, BendTEAPOT)): print "Node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("Can't add StraigtError around a Bend! Stop!") nodei = lattice.getNodes()[nodeIndexi] nodef = lattice.getNodes()[nodeIndexf] errori = rotationi(angle, rhoi, theta, lengtherr, et, rotype) errorf = rotationf(angle, rhoi, theta, lengtherr, et, rotype) addErrorNodeAsChild_I(lattice, nodei, errori) addErrorNodeAsChild_F(lattice, nodef, errorf)
def addErrorNode(lattice, position, Error_Node): """ This will put one error node into the lattice """ length_tolerance = 0.0001 lattice.initialize() position_start = position position_stop = position + Error_Node.getLength() (node_start_ind, node_stop_ind, z, ind) = (-1, -1, 0.0, 0) for node in lattice.getNodes(): if(position_start >= z and position_start <= z + node.getLength()): node_start_ind = ind if(position_stop >= z and position_stop <= z + node.getLength()): node_stop_ind = ind ind += 1 z += node.getLength() """ Check that between start and end there are only non-modified drift elements. If space charge was added first - that is a problem. The collimation should be added first. """ for node in lattice.getNodes()[node_start_ind:node_stop_ind + 1]: """ print "debug node = ", node.getName(), " type = ", node.getType(),\ " L = ", node.getLength() """ if(not isinstance(node, DriftTEAPOT)): print "Non-drift node = ", node.getName(), " type = ",\ node.getType(), " L = ", node.getLength() orbitFinalize("We have non-drift element at the place of \ the error node! Stop!") """ if(node.getNumberOfChildren() != 4): print "Node = ", node.getName()," type = ", node.getType(),\ " L = ", node.getLength(), " N child nodes = ",\ node.getNumberOfChildren() orbitFinalize("Drift element was modified with additional \ functionality (SC or something else)! Add collimation first! \ Stop!") """ """ Make array of nodes with error node in the center and two possible drifts, if their length is more than length_tollerance [m] """ nodes_new_arr = [Error_Node,] drift_node_start = lattice.getNodes()[node_start_ind] drift_node_stop = lattice.getNodes()[node_stop_ind] """ Now create two drift nodes: before and after the error node. If the length of either of these additional drifts is less than length_tollerance [m], skip this drift. """ if(position_start > lattice.getNodePositionsDict()[drift_node_start][0] +\ length_tolerance): drift_node_start_new = DriftTEAPOT(drift_node_start.getName()) drift_node_start_new.setLength(position_start -\ lattice.getNodePositionsDict()[drift_node_start][0]) nodes_new_arr.insert(0, drift_node_start_new) if(position_stop < lattice.getNodePositionsDict()[drift_node_stop][1] -\ length_tolerance): drift_node_stop_new = DriftTEAPOT(drift_node_stop.getName()) drift_node_stop_new.setLength(lattice.getNodePositionsDict()[drift_node_stop][1] -\ position_stop) nodes_new_arr.append(drift_node_stop_new) """ Now modify the lattice by replacing the old part with the new nodes """ lattice.getNodes()[node_start_ind:node_stop_ind + 1] = nodes_new_arr """ Initialize the lattice """ lattice.initialize()
def trackTwissData(self, alpha, beta, direction = "x"): """ Returns the tuple ([(position, phase advance/2/pi),...], [(position, alpha),...],[(position,beta),...] ). The tracking starts from the values specified as the initial parameters. The possible values for direction parameter "x" or "y". """ if(direction.lower() != "x" and direction.lower() != "y"): orbitFinalize("Class orbit.matrix_lattice.MATRIX_Lattice, method trackTwissData(...): direction should be x or y.") #track twiss eps_length = 0.00001 # 10^-6 meter dir_ind = 0 if(direction.lower() == "y"): dir_ind = 2 gamma = (1.0+alpha*alpha)/beta track_m = Matrix(3,3) track_m.unit() track_v = PhaseVector(3) track_v.set(0,alpha) track_v.set(1,beta) track_v.set(2,gamma) position = 0. pos_arr = [] alpha_arr = [] beta_arr = [] #phi is for tune accumulation phi = 0. #phase advance mu_arr = [] #put in array the initial twiss pos_arr.append(position) mu_arr.append(phi) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) position_old = position beta_old = beta #count = 0 for matrixNode in self.getNodes(): if(isinstance(matrixNode,BaseMATRIX) == True): beta = track_v.get(1) if(abs(position_old-position) > eps_length or abs(beta_old - beta) > eps_length): pos_arr.append(position) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) mu_arr.append(phi/(2*math.pi)) mt = matrixNode.getMatrix() ind0 = 0+dir_ind ind1 = 1+dir_ind track_m.set(0,0,mt.get(ind0,ind0)*mt.get(ind1,ind1)+mt.get(ind0,ind1)*mt.get(ind1,ind0)) track_m.set(0,1,-mt.get(ind0,ind0)*mt.get(ind1,ind0)) track_m.set(0,2,-mt.get(ind0,ind1)*mt.get(ind1,ind1)) track_m.set(1,0,-2*mt.get(ind0,ind0)*mt.get(ind0,ind1)) track_m.set(1,1,mt.get(ind0,ind0)*mt.get(ind0,ind0)) track_m.set(1,2,mt.get(ind0,ind1)*mt.get(ind0,ind1)) track_m.set(2,0,-2*mt.get(ind1,ind0)*mt.get(ind1,ind1)) track_m.set(2,1,mt.get(ind1,ind0)*mt.get(ind1,ind0)) track_m.set(2,2,mt.get(ind1,ind1)*mt.get(ind1,ind1)) alpha_0 = track_v.get(0) beta_0 = track_v.get(1) delta_phi = math.atan( mt.get(ind0,ind1)/( beta_0*mt.get(ind0,ind0) - alpha_0*mt.get(ind0,ind1))) phi = phi + delta_phi track_v = track_m.mult(track_v) position_old = position beta_old = beta_0 position = position + matrixNode.getLength() #count = count + 1 pos_arr.append(position) alpha_arr.append(track_v.get(0)) beta_arr.append(track_v.get(1)) mu_arr.append(phi/(2*math.pi)) #pack the resulting tuple tune = phi/(2*math.pi) graph_alpha_arr = [] graph_beta_arr = [] graph_mu_arr = [] for i in range(len(pos_arr)): graph_mu_arr.append((pos_arr[i], mu_arr[i])) graph_alpha_arr.append((pos_arr[i],alpha_arr[i])) graph_beta_arr.append((pos_arr[i],beta_arr[i])) return (graph_mu_arr,graph_alpha_arr,graph_beta_arr)
def trackDispersionData(self,momentum,mass, disp, disp_p, direction = "x"): """ Returns the tuple ([(position, disp),...],[(position,disp_p),...] ). The tracking starts from the values specified as the initial parameters. The possible values for direction parameter "x" or "y". """ if(direction.lower() != "x" and direction.lower() != "y"): orbitFinalize("Class orbit.matrix_lattice.MATRIX_Lattice, method trackDispersionData(...): direction should be x or y.") #track dispersion eps_length = 0.00001 # 10^-6 meter dir_ind = 0 if(direction.lower() == "y"): dir_ind = 2 track_m = Matrix(3,3) track_m.unit() track_m.set(2,0,0.) track_m.set(2,1,0.) track_m.set(2,2,1.) track_v = PhaseVector(3) #kinematics coefficient calculation Etotal = math.sqrt(momentum**2 + mass**2) beta = momentum/Etotal gamma = Etotal/mass Ekin = Etotal - mass m_coeff = momentum*momentum/(mass + Ekin) track_v.set(0,disp) track_v.set(1,disp_p) track_v.set(2,1.) position = 0. pos_arr = [] disp_arr = [] disp_p_arr = [] #put in array the initial dispersions pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) position_old = position disp_old = disp #count = 0 for matrixNode in self.getNodes(): if(isinstance(matrixNode,BaseMATRIX) == True): disp = track_v.get(0) if(abs(position_old-position) > eps_length or abs(disp_old - disp) > eps_length): pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) disp_old = disp position_old = position mt = matrixNode.getMatrix() ind0 = 0+dir_ind ind1 = 1+dir_ind track_m.set(0,0,mt.get(ind0,ind0)) track_m.set(0,1,mt.get(ind0,ind1)) track_m.set(1,0,mt.get(ind1,ind0)) track_m.set(1,1,mt.get(ind1,ind1)) track_m.set(0,2,mt.get(ind0,5)*m_coeff) track_m.set(1,2,mt.get(ind1,5)*m_coeff) track_v = track_m.mult(track_v) position = position + matrixNode.getLength() pos_arr.append(position) disp_arr.append(track_v.get(0)) disp_p_arr.append(track_v.get(1)) #pack the resulting tuple graph_disp_arr = [] graph_disp_p_arr = [] for i in range(len(pos_arr)): graph_disp_arr.append((pos_arr[i],disp_arr[i])) graph_disp_p_arr.append((pos_arr[i],disp_p_arr[i])) return (graph_disp_arr,graph_disp_p_arr)