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

Last change on this file since 232 was 232, checked in by lemeur, 12 years ago

ajustement parametres graphiques

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