[5b822e5] | 1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
---|
| 2 | * *
|
---|
| 3 | * --<--<-- A fast simulator --<--<-- *
|
---|
| 4 | * / --<--<-- of particle --<--<-- *
|
---|
| 5 | * ----HECTOR----< *
|
---|
| 6 | * \ -->-->-- transport through -->-->-- *
|
---|
| 7 | * -->-->-- generic beamlines -->-->-- *
|
---|
| 8 | * *
|
---|
| 9 | * JINST 2:P09005 (2007) *
|
---|
| 10 | * X Rouby, J de Favereau, K Piotrzkowski (CP3) *
|
---|
| 11 | * http://www.fynu.ucl.ac.be/hector.html *
|
---|
| 12 | * *
|
---|
| 13 | * Center for Cosmology, Particle Physics and Phenomenology *
|
---|
| 14 | * Universite catholique de Louvain *
|
---|
| 15 | * Louvain-la-Neuve, Belgium *
|
---|
| 16 | * *
|
---|
| 17 | * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
---|
| 18 |
|
---|
| 19 | /// \file H_BeamLine.cc
|
---|
| 20 | /// \brief Reads external files and retrieves features of the real beam optical elements
|
---|
| 21 |
|
---|
| 22 | // c++ #includes
|
---|
| 23 | #include <iostream>
|
---|
| 24 | #include <fstream>
|
---|
| 25 | #include <sstream>
|
---|
| 26 | #include <cstdlib>
|
---|
| 27 |
|
---|
| 28 | // local #includes
|
---|
| 29 | #include "H_BeamLine.h"
|
---|
| 30 | #include "H_BeamLineParser.h"
|
---|
| 31 | #include "H_RectEllipticAperture.h"
|
---|
| 32 | #include "H_RectangularAperture.h"
|
---|
| 33 | #include "H_EllipticAperture.h"
|
---|
| 34 | #include "H_CircularAperture.h"
|
---|
| 35 | #include "H_RectangularDipole.h"
|
---|
| 36 | #include "H_SectorDipole.h"
|
---|
| 37 | #include "H_HorizontalQuadrupole.h"
|
---|
| 38 | #include "H_VerticalQuadrupole.h"
|
---|
| 39 | #include "H_HorizontalKicker.h"
|
---|
| 40 | #include "H_VerticalKicker.h"
|
---|
| 41 | #include "H_RectangularCollimator.h"
|
---|
| 42 | #include "H_Marker.h"
|
---|
| 43 |
|
---|
| 44 | using namespace std;
|
---|
| 45 |
|
---|
| 46 | // Caution : mad conventions for vertically(horizontally) focusing quadrupoles
|
---|
| 47 | // are opposite to Wille's. See fill() for more details.
|
---|
| 48 |
|
---|
| 49 | H_BeamLine::H_BeamLine(): H_AbstractBeamLine(),
|
---|
| 50 | direction(1), ips(0), ipx(0), ipy(0), iptx(0), ipty(0) {
|
---|
| 51 | }
|
---|
| 52 |
|
---|
| 53 | H_BeamLine::H_BeamLine(const int si, const float length) : H_AbstractBeamLine(length),
|
---|
| 54 | direction((si >= abs(si)) ? 1 : -1), ips(0), ipx(0), ipy(0), iptx(0), ipty(0) {
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | H_BeamLine::H_BeamLine(const H_BeamLine& beam) : H_AbstractBeamLine(beam),
|
---|
| 58 | direction(beam.direction), ips(beam.ips), ipx(beam.ipx), ipy(beam.ipy), iptx(beam.iptx), ipty(beam.ipty) {
|
---|
| 59 | }
|
---|
| 60 |
|
---|
| 61 | H_BeamLine& H_BeamLine::operator=(const H_BeamLine& beam) {
|
---|
| 62 | if(this==&beam) return *this;
|
---|
| 63 | H_AbstractBeamLine::operator=(beam); // call the mother's operator=
|
---|
| 64 | direction = beam.direction;
|
---|
| 65 | ips = beam.ips;
|
---|
| 66 | ipx = beam.ipx;
|
---|
| 67 | ipy = beam.ipy;
|
---|
| 68 | iptx = beam.iptx;
|
---|
| 69 | ipty = beam.ipty;
|
---|
| 70 | return *this;
|
---|
| 71 | }
|
---|
| 72 |
|
---|
| 73 | void H_BeamLine::findIP(const string& filename, const string& ipname) {
|
---|
| 74 | // searches for the IP position in the extended table.
|
---|
| 75 | ifstream tabfile(filename.c_str());
|
---|
| 76 | if (! tabfile.is_open()) cout << "<H_BeamLine> ERROR: I Can't open \"" << filename << "\"" << endl;
|
---|
| 77 | bool found = false;
|
---|
| 78 | int N_col=0;
|
---|
| 79 | string headers[40]; // table of all column headers
|
---|
| 80 | int header_type[40]; // table of all column types
|
---|
| 81 |
|
---|
| 82 | string temp_string;
|
---|
| 83 | H_BeamLineParser e;
|
---|
| 84 | istringstream curstring;
|
---|
| 85 |
|
---|
| 86 | while ( getline(tabfile,temp_string)) {
|
---|
| 87 | curstring.clear(); // needed when using istringstream::str(string) several times !
|
---|
| 88 | curstring.str(temp_string);
|
---|
| 89 |
|
---|
| 90 | // gets the features of each element
|
---|
| 91 | if (found) {
|
---|
| 92 | for (int col=0; col < N_col; col++) e.setProperties(curstring,header_type[col]);
|
---|
| 93 | if(strstr(e.name.c_str(),ipname.c_str())) {
|
---|
| 94 | ips = e.s; //e.printProperties();
|
---|
| 95 | ipx = e.x;
|
---|
| 96 | ipy = e.y;
|
---|
| 97 | iptx = e.px*URAD;
|
---|
| 98 | ipty = e.py*URAD;
|
---|
| 99 | }
|
---|
| 100 | } else if (strstr(temp_string.c_str(),"K0L")) { //searches for the beginning of the element list.
|
---|
| 101 | found = true;
|
---|
| 102 |
|
---|
| 103 | // reads the title of each column
|
---|
| 104 | while(curstring.good()) { curstring >> headers[N_col]; if(headers[N_col]!="*") N_col++;}
|
---|
| 105 | if(VERBOSE) cout << N_col << " columns identified" << endl;
|
---|
| 106 |
|
---|
| 107 | // identifies each column
|
---|
| 108 | for (int col=0; col< N_col; col++) header_type[col] = column_identification(headers[col]);
|
---|
| 109 |
|
---|
| 110 | getline(tabfile,temp_string); // skip one line
|
---|
| 111 | } // if(... "K0L")
|
---|
| 112 | } // while (!eof)
|
---|
| 113 |
|
---|
| 114 | if (!found) cout << "<H_BeamLine> ERROR ! IP not found." << endl;
|
---|
| 115 | tabfile.close();
|
---|
| 116 | }
|
---|
| 117 |
|
---|
| 118 | double* H_BeamLine::getIPProperties() {
|
---|
| 119 | double* temp = new double[4];
|
---|
| 120 | temp[0] = ipx;
|
---|
| 121 | temp[1] = ipy;
|
---|
| 122 | temp[2] = iptx;
|
---|
| 123 | temp[3] = ipty;
|
---|
| 124 | return temp;
|
---|
| 125 | }
|
---|
| 126 |
|
---|
| 127 |
|
---|
| 128 | void H_BeamLine::fill(const string& filename, const int dir, const string& ipname) {
|
---|
| 129 | string headers[40]; // table of all column headers
|
---|
| 130 | int header_type[40]; // table of all column types
|
---|
| 131 | findIP(filename,ipname);
|
---|
| 132 | ifstream tabfile(filename.c_str());
|
---|
| 133 | if (! tabfile.is_open()) cout << "<H_BeamLine> ERROR: I Can't open \"" << filename << "\"" << endl;
|
---|
| 134 | if(VERBOSE) {
|
---|
| 135 | cout<<"Using file : "<< filename <<" in the "<<((direction>0)?"positive":"negative")<<" direction."<<endl;
|
---|
| 136 | cout<<"IP was found at position : "<<ips<<endl<<endl;
|
---|
| 137 | }
|
---|
| 138 | bool found = false; // found = true when the beginning of the element list is reached
|
---|
| 139 | int type, N_col=0;
|
---|
| 140 | float previous_betax =0, previous_betay=0; // needed when direction ==1
|
---|
| 141 | float previous_dx =0, previous_dy=0; // needed when direction ==1
|
---|
| 142 | float previous_x =0, previous_y=0; // needed when direction ==1
|
---|
| 143 |
|
---|
| 144 | string temp_string;
|
---|
| 145 | H_BeamLineParser e;
|
---|
| 146 | istringstream curstring;
|
---|
| 147 | H_OpticalElement *el = 0;
|
---|
| 148 | H_Aperture * ap = 0;
|
---|
| 149 |
|
---|
| 150 |
|
---|
| 151 | while (getline(tabfile,temp_string)) {
|
---|
| 152 | curstring.clear(); // needed when using several tims istringstream::str(string)
|
---|
| 153 | curstring.str(temp_string);
|
---|
| 154 |
|
---|
| 155 | // gets the features of each element
|
---|
| 156 | if (found) {
|
---|
| 157 | // reads each column
|
---|
| 158 | for (int col=0; col < N_col; col++) {
|
---|
| 159 | e.setProperties(curstring,header_type[col]);
|
---|
| 160 | }
|
---|
| 161 | //e.printProperties();
|
---|
| 162 |
|
---|
| 163 | type =0; //init
|
---|
| 164 | if(e.k0l!=0) { if(strstr(e.name.c_str(),"MB.")) type = SDIPOLE; else type = RDIPOLE;} //all SBEND seems to be called MB.xxxxx.xx
|
---|
| 165 | else if(e.k1l!=0) type = (e.k1l>0)?HQUADRUPOLE:VQUADRUPOLE;
|
---|
| 166 | else if(e.hkick!=0) type = HKICKER;
|
---|
| 167 | else if(e.vkick!=0) type = VKICKER;
|
---|
| 168 | else if(strstr(e.name.c_str(),"DRIFT")) type=DRIFT;
|
---|
| 169 | else if((strstr(e.name.c_str(),"DFB"))||(strstr(e.name.c_str(),"TAS"))||(strstr(e.name.c_str(),"TAN"))||(strstr(e.name.c_str(),"TCL"))) type = RCOLLIMATOR;
|
---|
| 170 | else if(strstr(e.name.c_str(),ipname.c_str())) { type=IP; }
|
---|
| 171 | else type=MARKER;
|
---|
| 172 |
|
---|
| 173 | e.s = (e.s > ips) ? (e.s -ips - e.l)*(direction) : (e.s-ips)*(direction);
|
---|
| 174 |
|
---|
| 175 | el=0; //init
|
---|
| 176 | switch(type) {
|
---|
| 177 | case RDIPOLE: { el = new H_RectangularDipole(e.name.c_str(),e.s,dir*e.k0l/e.l,e.l); } break;
|
---|
| 178 | case SDIPOLE: { el = new H_SectorDipole(e.name.c_str(),e.s,dir*e.k0l/e.l,e.l); } break;
|
---|
| 179 | case VQUADRUPOLE: { el = new H_VerticalQuadrupole(e.name.c_str(),e.s,-(e.k1l/e.l),e.l); } break;
|
---|
| 180 | case HQUADRUPOLE: { el = new H_HorizontalQuadrupole(e.name.c_str(),e.s,-(e.k1l/e.l),e.l); } break;
|
---|
| 181 | case VKICKER: { el = new H_VerticalKicker(e.name.c_str(),e.s,e.vkick,e.l); } break;
|
---|
| 182 | case HKICKER: { el = new H_HorizontalKicker(e.name.c_str(),e.s,e.hkick,e.l); } break;
|
---|
| 183 | case RCOLLIMATOR: { el = new H_RectangularCollimator(e.name.c_str(),e.s,e.l); } break;
|
---|
| 184 | case DRIFT: {previous_betax = e.betx; previous_betay = e.bety; previous_dx = e.dx; previous_dy = e.dy; previous_x = e.x; previous_y = e.y;} break;
|
---|
| 185 | case IP: { el = new H_Marker(e.name.c_str(),e.s); } break;
|
---|
| 186 | default: break;
|
---|
| 187 | }
|
---|
| 188 |
|
---|
| 189 | if(el!=0) {
|
---|
| 190 | ap = 0; //init
|
---|
| 191 | if(e.aper_1 !=0 || e.aper_2 !=0 || e.aper_3 !=0 || e.aper_4 != 0) {
|
---|
| 192 | e.aper_1 *= URAD;
|
---|
| 193 | e.aper_2 *= URAD;
|
---|
| 194 | e.aper_3 *= URAD;
|
---|
| 195 | e.aper_4 *= URAD; // in [m] in the tables !
|
---|
| 196 |
|
---|
| 197 | if(strstr(e.apertype.c_str(),"RECTELLIPSE"))
|
---|
| 198 | ap = new H_RectEllipticAperture(e.aper_1,e.aper_2,e.aper_3,e.aper_4,0,0);
|
---|
| 199 | else if(strstr(e.apertype.c_str(),"CIRCLE"))
|
---|
| 200 | ap = new H_CircularAperture(e.aper_1,0,0);
|
---|
| 201 | else if(strstr(e.apertype.c_str(),"RECTANGLE"))
|
---|
| 202 | ap = new H_RectangularAperture(e.aper_1,e.aper_2,0,0);
|
---|
| 203 | else if(strstr(e.apertype.c_str(),"ELLIPSE"))
|
---|
| 204 | ap = new H_EllipticAperture(e.aper_1,e.aper_2,0,0);
|
---|
| 205 | }
|
---|
| 206 |
|
---|
| 207 | if (direction<0) {
|
---|
| 208 | el->setBetaX(e.betx); el->setBetaY(e.bety);
|
---|
| 209 | el->setDX(e.dx); el->setDY(e.dy);
|
---|
| 210 | el->setRelX(e.x); el->setRelY(e.y);
|
---|
| 211 | } else {
|
---|
| 212 | el->setBetaX(previous_betax); el->setBetaY(previous_betay);
|
---|
| 213 | el->setDX(previous_dx); el->setDY(previous_dy);
|
---|
| 214 | el->setRelX(previous_x); el->setRelY(previous_y);
|
---|
| 215 | }
|
---|
| 216 | if(ap!=0) {
|
---|
| 217 | el->setAperture(ap);
|
---|
| 218 | delete ap;
|
---|
| 219 | // if memory is allocated, i.e. if ap!=0,
|
---|
| 220 | // it wont be deallocated in H_OpticalElement::~H_OpticalElement
|
---|
| 221 | // ap should then be deleted here
|
---|
| 222 | } // memory leak-free!
|
---|
| 223 |
|
---|
| 224 | /// Parses all the elements from the beginning of the file,
|
---|
| 225 | /// but only keeps the ones from the IP till the desired length
|
---|
| 226 | if(e.s>=0 && e.s<beam_length) add(el);
|
---|
| 227 | else { delete el;}
|
---|
| 228 | // NB : if "el" is added to the beamline, it will be
|
---|
| 229 | // deleted by H_AbstractBeamLine::~H_AbstractBeamLine
|
---|
| 230 | // Otherwise, it should be deleted explicitly
|
---|
| 231 |
|
---|
| 232 | } // if(el!=0)
|
---|
| 233 | } // if (found)
|
---|
| 234 | else if(strstr(temp_string.c_str(),"K0L")) { // if (!found)
|
---|
| 235 | //searches for the beginning of the element list.
|
---|
| 236 | found = true;
|
---|
| 237 |
|
---|
| 238 | // reads the title of each column
|
---|
| 239 | while(curstring.good()) { curstring >> headers[N_col]; if(headers[N_col]!="*") N_col++;}
|
---|
| 240 | if(VERBOSE) cout << N_col << " columns identified" << endl;
|
---|
| 241 |
|
---|
| 242 | // identifies each column
|
---|
| 243 | for (int col=0; col< N_col; col++) {
|
---|
| 244 | header_type[col] = column_identification(headers[col]);
|
---|
| 245 | }
|
---|
| 246 | getline(tabfile,temp_string);
|
---|
| 247 | } // if temp_string <-> "K0L"
|
---|
| 248 |
|
---|
| 249 | } // while (!eof)
|
---|
| 250 | tabfile.close();
|
---|
| 251 | }
|
---|
| 252 |
|
---|