source: PSPA/Interface_Web/trunk/pspaWT/src/particleBeam.cc @ 224

Last change on this file since 224 was 224, checked in by touze, 12 years ago

embryon d'histo... à completer

File size: 15.2 KB
Line 
1#include "particleBeam.h"
2#include "mathematicalConstants.h"
3#include "PhysicalConstants.h"
4//#include <string>
5#include <stdio.h>
6#include <algorithm>
7
8#include "environmentVariables.h"
9
10
11
12particleBeam::particleBeam()  {
13  // rij_transportMoments_.resize(6);
14  // unsigned dim=0;
15  // unsigned k;
16  // for ( k=0; k < 6; k++){
17  //   rij_transportMoments_.at(k).resize(++dim);
18  // }
19  P0Transport_ = 0.0;
20  particleRepresentationOk_ = false;
21  momentRepresentationOk_ = false;
22}
23
24void particleBeam::clear() {
25  goodPartic_.clear();
26  rij_.raz();
27  P0Transport_ = 0.0;
28  particleRepresentationOk_ = false;
29  momentRepresentationOk_ = false;
30}
31
32int particleBeam::getNbParticles() const {
33  return goodPartic_.size();
34}
35
36const transportMoments&   particleBeam::getTransportMoments() const  { 
37    return rij_;
38}
39
40double particleBeam::getSigmaTransportij(unsigned i, unsigned j)  {
41  if ( i < 1 || i > 6 || j < 1 || j > 6 ) {
42    cerr << " particleBeam::getSigmaTransportij() indices out of range  " << endl;
43    return 0.0;
44  }
45  if ( !momentRepresentationOk_ ) {
46    cerr << " particleBeam::getSigmaTransportij() beam is not in moment representation " << endl;
47    return 0.0;
48  }
49
50  i--;
51  j--;
52  if ( j > i ) {
53    unsigned aux = i;
54    i = j;
55    j = aux;
56  }
57  return ( rij_.getMatrix().at(i) ).at(j);
58}
59
60
61double particleBeam::getUnnormalizedEmittanceX() {
62  double r = getSigmaTransportij(2,1);
63  double rac = (1 - r*r);
64  if ( rac <= 0.0 ) {
65    return 0.0;
66  }
67  rac = sqrt(1 - r*r);
68  return  10.*getSigmaTransportij(1,1) * getSigmaTransportij(2,2) * rac; // en pi.mm.mrad
69}
70
71double particleBeam::getP0Transport() const { 
72  return P0Transport_;
73}
74bool particleBeam::particleRepresentationOk() const {
75  return particleRepresentationOk_;
76}
77bool particleBeam::momentRepresentationOk() const {
78  return momentRepresentationOk_;
79}
80
81void  particleBeam::addParticle( bareParticle p)
82{
83  goodPartic_.push_back(p);
84}
85
86const vector<bareParticle>& particleBeam::getParticleVector() const
87{
88  return goodPartic_;
89}
90vector<bareParticle>& particleBeam::getParticleVector() 
91{
92  return goodPartic_;
93}
94
95
96bool  particleBeam::setFromTransport(string elLab, const nomdElements elem)
97{
98  string elementLabel = elLab;
99  // transformer le label en majuscules ; je ne suis pas sur que ca
100  // marchera a tous les coups (glm)
101  std::transform(elementLabel.begin(), elementLabel.end(), elementLabel.begin(), (int (*)(int))std::toupper);
102
103  cout << " particleBeam::setFromTransport on cherche element " << elementLabel << endl;
104  string buf;
105  ifstream infile;
106  string nameIn = WORKINGAREA + "transport.output";
107  infile.open(nameIn.c_str(), ios::in);
108  if (!infile) {
109    cerr << " particleBeam::setFromTransport : error re-opening transport output stream " << nameIn << endl;
110    return false;
111  }
112  //  else cout << " particleBeam::setFromTransport() : ouverture du fichier " << nameIn << endl;
113
114  string::size_type nn = string::npos;
115  while ( getline(infile, buf) ) {
116    //      cout << " buf= "  << buf << endl;
117    nn = buf.find(elementLabel);
118    //     cout << " string::npos= " << string::npos << " nn= " << nn << endl;
119    if ( nn != string::npos ) {
120      //          cout << " particleBeam::setFromTransport : element " << elementLabel << " trouve " << endl;
121      break;
122    }
123  }
124
125  if ( nn == string::npos ) {
126    cerr << " particleBeam::setFromTransport : element " << elementLabel << " non trouve dans le fichier  " << nameIn << endl;
127    return false;
128  }
129  if (elem.getElementType() == bend ) {
130    getline(infile, buf);
131    getline(infile, buf);
132  }
133  readTransportMoments(infile);
134  //  impressionDesMoments();
135  infile.close();
136  momentRepresentationOk_ = true;
137  return true;
138}
139
140
141bool particleBeam::setFromParmela(unsigned numeroElement, double referencefrequency) {
142  unsigned  k;
143  FILE* filefais;
144  string nomfilefais = WORKINGAREA + "parmdesz";
145  cout << " nom fichier desz : " << nomfilefais << endl;
146  filefais = fopen(nomfilefais.c_str(), "r");
147
148  if ( filefais == (FILE*)0 ) {
149    cerr << " particleBeam::setFromParmela() erreur a l'ouverture du fichier" << nomfilefais  << endl;; 
150    return false;
151  }
152  else cout << " particleBeam::setFromParmela() : ouverture du fichier " << nomfilefais << endl; 
153
154  parmelaParticle partic;
155  std::vector<parmelaParticle> faisceau;
156
157  cout << " particleBeam::setFromParmela : numeroElement = " << numeroElement << endl;
158  unsigned indexElement = numeroElement-1;
159 
160
161
162
163  int testNombrePartRef =0;
164  double phaseRef;
165
166  while( partic.readFromParmelaFile(filefais) > 0 ) {
167    if ( partic.ne == indexElement )
168      {
169        faisceau.push_back(partic);
170
171        if ( partic.np == 1 ) {
172          // en principe on est sur la particule de reference
173          if ( fabs(partic.xx) > EPSILON || fabs(partic.yy) > EPSILON || fabs(partic.xxp) > EPSILON  || fabs(partic.yyp) > EPSILON) {
174            printf(" ATTENTION part. reference douteuse  \n");
175            partic.imprim();
176          }
177          phaseRef = partic.phi;
178          TRIDVECTOR  posRef(partic.xx,partic.yy,0.0);
179          TRIDVECTOR betagammaRef(partic.xxp*partic.begamz, partic.yyp*partic.begamz, partic.begamz);
180          referenceParticle_ = bareParticle(posRef, betagammaRef);
181          testNombrePartRef++;
182          if ( testNombrePartRef != 1 ) {
183            cerr << " TROP DE PART. DE REF : " << testNombrePartRef << " !! " << endl;
184            return false;
185          }
186        }
187      }
188  }
189
190  if ( faisceau.size() == 0) 
191    {
192      cerr << " particleBeam::setFromParmela echec lecture  element " << numeroElement << endl;
193      return false;
194    }
195 
196  // facteur  c/ 360. pour calculer (c dphi) / (360.freq)
197  // avec freq en Mhz et dphi en degres et résultat en cm:
198  double FACTEUR =  83.3333;  // ameliorer la precision
199
200
201
202  // pour l'instant on choisit un centroid nul;
203  centroid_ = vector<double>(6,0.0);
204
205  goodPartic_.clear();
206  goodPartic_.resize(faisceau.size(), bareParticle());
207  double x,xp,y,yp;
208  double betagammaz;
209  double betaz;
210  double deltaz;
211  double dephas;
212  double g;
213  TRIDVECTOR  pos;
214  TRIDVECTOR betagamma;
215  // contrairement a ce qu'indique la notice PARMELA, dans parmdesz, les xp et yp
216  // sont donnes en radians
217  for ( k=0; k < faisceau.size(); k++) {
218    x=faisceau.at(k).xx;
219    xp=faisceau.at(k).xxp;
220    y=faisceau.at(k).yy;
221    yp=faisceau.at(k).yyp;
222
223    // dephasage par rapport a la reference 
224    dephas = faisceau.at(k).phi - phaseRef; // degrés
225    g = faisceau.at(k).wz/ERESTMeV;
226    betagammaz = faisceau.at(k).begamz;
227    betaz = betagammaz/(g+1.0);
228    deltaz = FACTEUR * betaz * dephas / referencefrequency;
229    x += xp * deltaz;
230    y += yp * deltaz;
231    pos.setComponents(x,y,deltaz);
232    betagamma.setComponents(xp*betagammaz, yp*betagammaz, betagammaz);
233    goodPartic_.at(k) = bareParticle(pos,betagamma);
234  }
235  particleRepresentationOk_ = true;
236  return true;
237}
238
239
240void particleBeam::getVariance(double& varx, double& vary, double& varz) const {
241  unsigned int k;
242  double x,y,z;
243  double xav = 0.;
244  double yav = 0.;
245  double zav = 0.;
246  double xavsq = 0.;
247  double yavsq = 0.;
248  double zavsq = 0.;
249
250  TRIDVECTOR pos;
251
252
253  for ( k = 0 ; k < goodPartic_.size(); k++) {
254    pos = goodPartic_.at(k).getPosition();
255    pos.getComponents(x,y,z);
256    //      partic_[k].getXYZ(x,y,z);
257    xav += x;
258    xavsq += x*x;
259    yav += y;
260    yavsq += y*y;
261    zav += z;
262    zavsq += z*z;
263  }
264
265  double aginv = double (goodPartic_.size());
266  aginv = 1.0/aginv;
267
268  varx =  aginv * ( xavsq - xav*xav*aginv );
269  vary =  aginv * ( yavsq - yav*yav*aginv );
270  varz =  aginv * ( zavsq - zav*zav*aginv );
271}
272
273
274void particleBeam::printAllXYZ() const {
275  cout << " dump du faisceau : " << endl;
276  cout <<  goodPartic_.size() << " particules " << endl;
277  unsigned int k;
278  for ( k = 0 ; k < goodPartic_.size(); k++)
279    {
280      double xx,yy,zz;
281      goodPartic_.at(k).getPosition().getComponents(xx,yy,zz);
282      cout << " part. numero " << k << "  x= " << xx << " y= " << yy  << " z= " << zz << endl;
283    }
284}
285
286
287
288void particleBeam::Zrange(double& zmin, double& zmax) const {
289  double z;
290  zmin = GRAND;
291  zmax = -zmin;
292
293  unsigned int k;
294  for ( k = 0 ; k < goodPartic_.size(); k++)
295    {
296      z = goodPartic_.at(k).getZ();
297      if ( z < zmin ) zmin = z;
298      else if ( z > zmax) zmax = z;         
299    }
300}
301
302
303
304string particleBeam::FileOutputFlow() const {
305  ostringstream sortie;
306  unsigned int k;
307  for ( k = 0 ; k < goodPartic_.size(); k++)
308    {
309      sortie << goodPartic_.at(k).FileOutputFlow() << endl;
310    }
311  sortie << endl;
312  return sortie.str();
313}
314
315bool particleBeam::FileInput( ifstream& ifs) {
316  bool test = true;
317  string dum1, dum2;
318  double dummy;
319  if ( !( ifs >> dum1 >> dum2 >> dummy) ) return false;
320 
321  bareParticle pp;
322  while ( pp.FileInput(ifs) )
323    {
324      addParticle( pp);
325    }
326  return test;
327}
328
329void particleBeam::buildMomentRepresentation() {
330
331  unsigned k,j,m;
332  double auxj, auxm;
333  if ( !particleRepresentationOk_)
334    {
335      cerr << " particleBeam::buildMomentRepresentation() vecteur de particules invalide" << endl;
336      return;
337    }
338
339  cout << " buildMomentRepresentation " << endl;
340  //  printAllXYZ();
341
342  double gref = referenceParticle_.getGamma() - 1.0;
343  double P_reference_MeV_sur_c = sqrt( gref*(gref+2) );
344
345  // initialisation des moments
346  razDesMoments();
347
348  // accumulation
349  TRIDVECTOR pos;
350  TRIDVECTOR begam;
351  double gamma;
352  double begamz;
353  double g;
354  double PMeVsc;
355  double del;
356  vector<double> part(6);
357
358    vector< vector<double> >& matrice = rij_.getMatrix();
359
360
361  for (k=0; k < goodPartic_.size(); k++) {
362    gamma = goodPartic_.at(k).getGamma();
363    pos = goodPartic_.at(k).getPosition();
364    begam= goodPartic_.at(k).getBetaGamma();
365    begamz = begam.getComponent(2);
366    g = gamma -1.0;
367    PMeVsc = sqrt( g*(g+2) );
368    del = 100.0 * ( PMeVsc -  P_reference_MeV_sur_c ) / P_reference_MeV_sur_c ; // en %
369
370    part[0] = pos.getComponent(0);
371    part[1] = begam.getComponent(0)/begamz;
372    part[2] = pos.getComponent(1);
373    part[3] = begam.getComponent(1)/begamz;
374    part[4] = pos.getComponent(2);
375    part[5] = del;
376
377    for ( j = 0; j < 6; j++) {
378      auxj = part.at(j) - centroid_.at(j);
379      for (m=0; m <= j; m++) 
380        {
381          auxm = part.at(m) - centroid_.at(m);
382
383          ( matrice.at(j) ).at(m) += auxj*auxm;
384          //      ( rij_transportMoments_.at(j) ).at(m) += auxj*auxm;
385
386
387          //          cout << " j= " << j << " m= " << m << " rjm= " << ( rij_transportMoments_.at(j) ).at(m) << endl;
388        }
389    }
390  }
391
392
393  // moyenne
394  double facmoy = 1.0/double( goodPartic_.size() );
395  for ( j = 0; j < 6; j++) {
396        ( matrice.at(j) ).at(j) = sqrt(( matrice.at(j) ).at(j) * facmoy );
397  }
398
399  for ( j = 0; j < 6; j++) {
400    auxj =  ( matrice.at(j) ).at(j);
401    for (m=0; m < j; m++) {
402      auxm = ( matrice.at(m) ).at(m);
403      (  matrice.at(j) ).at(m) *= facmoy/(auxj * auxm);
404    }
405  }
406   
407  // les longueurs sont en cm
408  // les angles en radians, on passe en mrad;
409
410  double uniteAngle = 1.0e+3;
411  ( matrice.at(1) ).at(1)  *= uniteAngle;
412  ( matrice.at(3) ).at(3)  *= uniteAngle;
413  P0Transport_ = 1.0e-3*ERESTMeV*P_reference_MeV_sur_c;
414
415  //  cout << " buildmomentrepresentation impression des moments " << endl;
416  //  impressionDesMoments();
417
418  momentRepresentationOk_ = true;
419}
420
421void particleBeam::impressionDesMoments() const {
422  rij_.impression();
423}
424
425void particleBeam::razDesMoments() {
426  rij_.raz();
427}
428
429
430void particleBeam::readTransportMoments(ifstream& inp) {
431rij_.readFromTransportOutput(inp);
432}
433
434double particleBeam::getXmaxRms() {
435  if ( !momentRepresentationOk_ ) buildMomentRepresentation();
436  return ( rij_.getMatrix().at(0) ).at(0);
437  // return ( rij_transportMoments_.at(0) ).at(0);
438}
439
440void particleBeam::donneesDessinEllipseXxp(vector<double>& xcor, vector<double>& ycor) {
441  int k;
442  double x,y;
443
444  if ( !momentRepresentationOk_ ) return;
445
446  xcor.clear();
447  ycor.clear();
448
449  double xm = ( rij_.getMatrix().at(0) ).at(0);
450  double ym = ( rij_.getMatrix().at(1) ).at(1);
451  double r  = ( rij_.getMatrix().at(1) ).at(0);
452
453  cout <<  " racs11= " << xm << " racs22= " << ym << " r12= " << r << endl;
454
455
456  int nbintv = 50;
457  if ( xm == 0.0 ) return;
458  double pas = 2.0 * xm / nbintv;
459
460  //  cout << " r= " << r << endl;
461  double rac = (1 - r*r);
462  if ( rac > 0.0 ) 
463    {
464      cout << " cas rac > " << endl;
465      rac = sqrt(1 - r*r);
466      double alpha = -r / rac;
467      double beta = xm / ( ym * rac);
468      //  double gamma = ym / ( xm * rac );
469      double epsil = xm * ym * rac;
470      double fac1 = -1.0 / ( beta * beta);
471      double fac2 = epsil/beta;
472      double fac3 = -alpha/beta;
473      double aux;
474      for ( k=0; k < nbintv; k++)
475        {
476          x = -xm + k*pas;
477          aux = fac1 * x * x + fac2;
478          //     cout << " aux2= " << aux << endl;
479          if ( aux <= 0.0 )
480            {
481              aux = 0.0;
482            }
483          else aux = sqrt(aux);
484     
485          //        y = fac3*x;
486          y = fac3*x + aux;
487          xcor.push_back(x);
488          ycor.push_back(y);
489        }
490
491      for ( k=0; k <= nbintv; k++)
492        {
493          x = xm - k*pas;
494          aux =  fac1 * x * x + fac2;
495          if ( aux <= 0.0 ) 
496            {
497              aux = 0.0;
498            }
499          else aux = sqrt(aux);
500          //   y = fac3*x;
501          y = fac3*x - aux;
502          xcor.push_back(x);
503          ycor.push_back(y);
504        }
505    }
506  else
507    // cas degenere
508    {
509      cout << " cas degenere " << endl;
510      double fac = ym/xm;
511      for ( k=0; k < nbintv; k++)
512        {
513          x = -xm + k*pas;
514          y = fac*x;
515          xcor.push_back(x);
516          ycor.push_back(y);
517        }
518       
519    }
520}
521
522void particleBeam::histogramme(vector<double>&xcor,vector<int>& hist,int& cnts)
523{
524  double gammin= GRAND;
525  double gammax= -gammin;
526  double Emoy= 0.0;
527  double ecatyp= 0.0;
528
529  for (unsigned int k = 0; k < goodPartic_.size(); k++)
530    {
531      double gamma = goodPartic_.at(k).getGamma();
532      double EMev = (gamma-1.0)*ERESTMeV;
533      if (gamma < gammin) gammin = gamma;
534      else if (gamma > gammax) gammax = gamma;
535      Emoy += EMev;
536      ecatyp += EMev*EMev;
537    }
538
539  double sum= (float)goodPartic_.size();
540  Emoy /= sum;
541  ecatyp /= sum;
542  ecatyp = sqrt(abs(ecatyp-Emoy*Emoy));
543
544  double Emin = (gammin-1.0)*ERESTMeV;
545  double Emax = (gammax-1.0)*ERESTMeV;
546  cout << "energie cinetique -moyenne " << Emoy << " Mev " << "-mini " << Emin << " Mev " << "-maxi " << Emax << " Mev " << "ecart type " << ecatyp*1000.0 << " Kev" << endl;
547
548  vector<double> Eshf;
549  for (unsigned int k = 0; k < goodPartic_.size(); k++)
550    {
551      double gamma = goodPartic_.at(k).getGamma();
552      double EMev = (gamma-1.0)*ERESTMeV;
553      Eshf.push_back(EMev-Emoy);
554    }
555
556  //////////////////////////////////////////////////////////////////////////////
557 
558  // demi fenetre en energie, et pas de l'histogramme
559  double hfene= max(3.*ecatyp-Emoy,Emoy-3.*ecatyp);
560  double hpas = hfene/50.;
561
562  cout << "demi fenetre " << hfene << ", hpas= " << hpas << endl;
563
564  double vmin = -hfene;
565  double dfen = 2.*hfene;
566  int ihist = dfen/hpas;
567  double phist = ihist*hpas;
568  double dpas = hpas-(dfen-phist);
569  if(dpas <= hpas*1.e-03) {
570    ihist++;
571    phist= ihist*hpas;
572  }
573  double vmax= vmin+hpas*ihist;
574 
575  cout << "'xAxisNumberOfBins= " << ihist <<", xAxisMinimum= " << vmin << ", xAxisMaximum= " << vmax << ", NParticules= " << Eshf.size() << ", phist " << phist << endl;
576
577  xcor= vector<double>(ihist);
578  for (unsigned i = 0; i < ihist; ++i) {
579    xcor[i]= vmin+i*hpas;
580  }
581
582  hist= vector<int>(ihist,0);
583  for (unsigned i = 0; i < Eshf.size(); ++i) {
584    double var= Eshf[i]-vmin;
585    if(var < 0 || var >= phist) cout<<"out of range "<<var<<", ("<< i<<")"<< endl;
586    int k= var/hpas;
587    int kk= (int)floor(var/hpas);
588    if(i%20 == 0) cout<<"v("<<i<<")= " <<var<<" ["<<k<<"-"<<kk<<"], "<<endl; 
589    hist[kk]++;
590  }
591
592  cnts= 0;
593  for (unsigned i = 0; i < ihist; ++i) {
594    if(hist.at(i) > 0) cnts++;
595    cout<<"("<<xcor.at(i)<<","<<hist.at(i)<<") ";
596  }
597  cout<< " ... cnts=  " << cnts << endl;
598}
Note: See TracBrowser for help on using the repository browser.