<commit_before>#include "Units.h"
#include "PointContactDZ.h"
using namespace GeFiCa;
//for the case which point contact may not fall right on the grid, it will case
//a great different potential on space close to point contact the current
//design does not include when point contact is close to boundary of the whole
//detector.
PointContactDZ::PointContactDZ(int nd, int nz, const char *name,
      const char *title) : RhoZ(nd, nz, name, title),
   Height(5*cm),
   Radius(3*cm),
   PointContactH(0),
   PointContactR(1*mm),
   HoleH(0),
   HoleR(0),
   HoleTaperW(0),
   HoleTaperH(0),
   TaperW(1*mm),
   TaperH(1*mm),
   CornerW(1*mm),
   CornerH(1*mm),
   GrooveW(0),
   GrooveH(0) { WrapAroundR=Radius; }
//_____________________________________________________________________________
//
void PointContactDZ::SetBoundary()
{
   for(int i=0;i<fN;i++) {
      if (fC2[i]-PointContactH<fdC2m[i]&&fC2[i]>PointContactH
            &&fC1[i]<PointContactR&&fC1[i]>-PointContactR)
         fdC2m[i]=fC2[i]-PointContactH;
      if(fC1[i]-PointContactR<fdC1m[i]&&fC1[i]>0&&fC2[i]<PointContactH)
         fdC1m[i]=fC1[i]-PointContactR;
      if(-fC1[i]-PointContactR<fdC1p[i]&&fC1[i]<0&&fC2[i]<PointContactH)
         fdC1p[i]=-fC1[i]-PointContactR;
      if(WrapAroundR-fC1[i]<fdC1p[i]&&fC1[i]<WrapAroundR&&i<fN1)
         fdC1p[i]=WrapAroundR-fC1[i];
      if(WrapAroundR+fC1[i]<fdC1p[i]&&fC1[i]>-WrapAroundR&&i<fN1)
         fdC1m[i]=WrapAroundR+fC1[i];
   }
   double k=TaperH/(TaperW);
   double b=-(Radius-TaperW)*k;

   for(int i=0;i<fN;i++) {
      if(fC2[i]<=fC1[i]*k+b) {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
      if(fC2[i]<=-fC1[i]*k+b) {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
      if(fC2[i]-(fC1[i]*k+b)<fdC2p[i]) {
         fdC2m[i]=fC2[i]-(k*fC1[i]+b);
         fdC1p[i]=fC1[i]-b/k-fC2[i]/k;
      }
      if(fC2[i]-(-k*fC1[i]+b)<fdC2m[i]) {
         fdC2m[i]=fC2[i]-(-fC1[i]*k+b);
         fdC1m[i]=-fC1[i]/k-b/k-fC2[i];
      }
   }
   double x1=HoleTaperW,
          y1=Height,
          x2=HoleR,
          y2=Height-HoleTaperH,
          x3=Radius-CornerW,
          y3=Height,
          x4=Radius,
          y4=Height-CornerH;
   // y = k x + b
   double k1=(y1-y2)/(x1-x2);
   double b1=y1-k1*x1;
   double k2=(y3-y4)/(x3-x4);
   double b2=y3-k2*x3;

   for (int i=0;i<fN;i++) {
      if (x1!=x2) {
         //right side of hole taper
         if (fC1[i]-fC2[i]/k1+b1/k1<fdC1m[i] && fC2[i]>y2 &&
               fC1[i]-fC2[i]/k1+b1/k1>0)
            fdC1m[i]=fC1[i]-fC2[i]/k1+b1/k1;
         //left side of hole taper
         if (-fC1[i]-fC2[i]/k1+b1/k1>0
               &&-fC1[i]-fC2[i]/k1+b1/k1<fdC1p[i]&&fC2[i]>y2)
            fdC1p[i]=-fC1[i]-fC2[i]/k1+b1/k1;
      } else { //x1==x2
         //right side of hole taper
         if (fC1[i]-x1<fdC1m[i] && fC2[i]>y2 && fC1[i]-x1>0) fdC1m[i]=fC1[i]-x1;
         //left side of hole taper
         if (-fC1[i]-x1>0&&-fC1[i]-x1<fdC1p[i]&&fC2[i]>y2) fdC1p[i]=-fC1[i]-x1;
      }
      //right side of hole taper
      if (fC1[i]-HoleR<fdC1m[i] && fC2[i]>HoleH && fC1[i]-HoleR>0)
          fdC1m[i]=fC1[i]-HoleR;
      //left side of hole
      if (-fC1[i]-HoleR>0&&-fC1[i]-HoleR<fdC1p[i]&&fC2[i]>HoleH)
         fdC1p[i]=-fC1[i]-HoleR;
      //left corner
      if (fC1[i]+fC2[i]/k2-b2/k2>0 && fC1[i]+fC2[i]/k2-b2/k2<fdC1m[i] &&
            fC2[i]>y4) fdC1m[i]=fC1[i]+fC2[i]/k2-b2/k2;
      //right corner
      if (-fC1[i]+fC2[i]/k2-b2/k2>0
            &&-fC1[i]+fC2[i]/k2-b2/k2<fdC1p[i]&&fC2[i]>y4)
         fdC1p[i]=-fC1[i]+fC2[i]/k2-b2/k2;
      //down right side of hole
      if (-fC2[i]+fC1[i]*k1+b1>0&&-fC2[i]+fC1[i]*k1+b1<fdC2p[i]&&fC2[i]>y2)
         fdC2p[i]=-fC2[i]+fC1[i]*k1+b1;
      //down right of corner
      if (-fC2[i]-fC1[i]*k2+b2>0&&-fC2[i]-fC1[i]*k2+b2<fdC2p[i]&&fC2[i]>y4)
         fdC2p[i]=-fC2[i]-fC1[i]*k2+b2;
      //down left side of hole
      if (-fC2[i]-fC1[i]*k1+b1>0&&-fC2[i]-fC1[i]*k1+b1<fdC2p[i]&&fC2[i]>y2)
         fdC2p[i]=-fC2[i]-fC1[i]*k1+b1;
      //down left of corner
      if (-fC2[i]+fC1[i]*k2+b2>0&&-fC2[i]+fC1[i]*k2+b2<fdC2p[i]&&fC2[i]>y4)
         fdC2p[i]=-fC2[i]+fC1[i]*k2+b2;
      //down center of hole
      if (y2-fC2[i]<fdC2p[i]&&fC1[i]>-HoleR&&fC1[i]<HoleR)
         fdC2p[i]=y2-fC2[i];
   }
}
//_____________________________________________________________________________
//
void PointContactDZ::InitializeGrid()
{
   // we want no grid point right on z-axis
   if (fN1%2==1) {
      Error("InitializeGrid", "Number of points in D can't be odd! Abort.");
      abort();
   }

   SetStepLength(2*Radius/(fN1-1),Height/(fN2-1));
   for(int i=fN;i-->0;) fC1[i]=fC1[i]-Radius;

   // set initial potential values
   for(int i=fN;i-->0;) {
      fV[i]=(V1+V0)/2;
      // set potential for inner electrodes
      if(fC1[i]>=-PointContactR && fC1[i]<=PointContactR
            && fC2[i]<=PointContactH) {
         fV[i]=V0;
         fIsFixed[i]=true;
      }
   }
   // set potential for outer electrodes
   for(int i=fN-1;i>=fN-fN1;i--) {
      fIsFixed[i]=true;
      fV[i]=V1;
   }
   for(int i=0;i<fN-fN1;i=i+fN1) {
      fIsFixed[i]=true;
      fIsFixed[i+fN1-1]=true;
      fV[i]=V1;
      fV[i+fN1-1]=V1;
   }
   for (int i=0;i<fN1;i++) {
      if(fC1[i]>=WrapAroundR||fC1[i]<=-WrapAroundR) {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
   }

   double x1=HoleR+HoleTaperW,
          y1=Height,
          x2=HoleR,
          y2=Height-HoleTaperH,
          x3=Radius-CornerW,
          y3=Height,
          x4=Radius,
          y4=Height-CornerH;
   double k1=(y1-y2)/(x1-x2);
   double b1=y1-k1*x1;
   double k2=(y3-y4)/(x3-x4);
   double b2=(y3-k2*x3);
   if(x3!=x4)
      for(int i=0;i<fN;i++) {
         if(fC2[i]>-k2*(fC1[i])+b2||(fC2[i]>k2*(fC1[i])+b2)) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }
   if(x1!=x2) {
      for (int i=0;i<fN;i++) {
         if(((fC2[i]>-k1*(fC1[i])+b1 && fC2[i]>y2))&&fC1[i]<0) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
         if(((fC2[i]>k1*(fC1[i])+b1 && fC2[i]>y2))&&fC1[i]>0) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }
   } else { //x1==x2
      for (int i=0;i<fN;i++) {
         if(fC1[i]<=x1&&fC1[i]>=-x1&&fC2[i]>=y2) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }
   }
   for (int i=0;i<fN;i++) {
      if(fC1[i]<=HoleR&&fC1[i]>=-HoleR&&fC2[i]>=Height-HoleH) {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
   }
   SetBoundary();
}
//_____________________________________________________________________________
//
#include <cmath>
#include <fstream>
using namespace std;
void PointContactDZ::Export2fieldgen(const char *output)
{
   ofstream file(output);
   file<<"# xtal_length "<<Height/mm<<endl;
   file<<"# xtal_radius "<<Radius/mm<<endl;
   file<<"# pc_length   "<<PointContactH/mm<<endl;
   file<<"# pc_radius   "<<PointContactR/mm<<endl;
   file<<"# taper_length "<<TaperH/mm<<endl;
   file<<"# wrap_around_radius "<<WrapAroundR/mm<<endl;
   file<<"# ditch_depth "<<GrooveH/mm<<endl;
   file<<"# ditch_thickness "<<GrooveW/mm<<endl;
   file<<"# xtal_grid "<<fdC1p[0]/mm<<endl;
   file<<"# impurity_z0 "<<fImpurity[0]*cm3<<endl;
   file<<"# impurity_gradient "
      <<(fImpurity[fN-1]-fImpurity[0])/fdC2p[0]*cm*cm3<<endl;
   file<<"# xtal_HV      "<<abs(V0-V1)/volt<<endl;
   file<<"# max_iterations "<<GetNsor()<<endl;
   file<<"#"<<endl;
   file<<"## r (mm), z (mm), V (V),  E (V/cm), E_r (V/cm), E_z (V/cm)"<<endl;
   for (int i=0;i<fN;i++) file<<fC1[i]<<" "<<fC2[i]<<" "<<fV[i]<<" "
      <<sqrt(fE1[i]*fE1[i]+fE2[i]*fE2[i])<<" "<<fE1[i]<<" "<<fE2[i]<<endl;
   file.close();
}
//_____________________________________________________________________________
//
void PointContactDZ::SetGridImpurity()
{
   X::SetGridImpurity();

   if (TaperW+WrapAroundR>Radius) {
      Error("SetGridImpurity", "TaperW(%.1fmm) + WrapAroundR(%.1fmm)"
            " > Radiu(%.1fmm). Abort!", TaperW/mm, WrapAroundR/mm, Radius/mm);
      abort();
   } else if (WrapAroundR-GrooveW<PointContactR) {
      Error("SetGridImpurity", "WrapAroundR(%.1fmm) - GrooveW(%.1fmm)"
            " < PointContactR(%.1fmm). Abort!",
            WrapAroundR/mm, GrooveW/mm, PointContactR/mm);
      abort();
   } else {
      for (int i=0; i<fN; i++) {
         if (((fC1[i]>WrapAroundR-GrooveW && fC1[i]<WrapAroundR) ||
                  (fC1[i]>-WrapAroundR && fC1[i]<-WrapAroundR+GrooveW))
               && fC2[i]<GrooveH) fImpurity[i]=0;
      }
   }
}
//_____________________________________________________________________________
//
double PointContactDZ::GetData(double x, double y, double z, double *data)
{
   //if (point in boundary) return V1;
   return XY::GetData(x,y,z,data);
}
<commit_msg>fix wraparoundr init<commit_after>#include "Units.h"
#include "PointContactDZ.h"
using namespace GeFiCa;
//for the case which point contact may not fall right on the grid, it will case
//a great different potential on space close to point contact the current
//design does not include when point contact is close to boundary of the whole
//detector.
PointContactDZ::PointContactDZ(int nd, int nz, const char *name,
      const char *title) : RhoZ(nd, nz, name, title),
   Height(5*cm),
   Radius(3*cm),
   PointContactH(0),
   PointContactR(1*mm),
   HoleH(0),
   HoleR(0),
   HoleTaperW(0),
   HoleTaperH(0),
   TaperW(1*mm),
   TaperH(1*mm),
   CornerW(1*mm),
   CornerH(1*mm),
   WrapAroundR(-1),
   GrooveW(0),
   GrooveH(0) {  }
//_____________________________________________________________________________
//
void PointContactDZ::SetBoundary()
{
   for(int i=0;i<fN;i++) {
      if (fC2[i]-PointContactH<fdC2m[i]&&fC2[i]>PointContactH
            &&fC1[i]<PointContactR&&fC1[i]>-PointContactR)
         fdC2m[i]=fC2[i]-PointContactH;
      if(fC1[i]-PointContactR<fdC1m[i]&&fC1[i]>0&&fC2[i]<PointContactH)
         fdC1m[i]=fC1[i]-PointContactR;
      if(-fC1[i]-PointContactR<fdC1p[i]&&fC1[i]<0&&fC2[i]<PointContactH)
         fdC1p[i]=-fC1[i]-PointContactR;
      if(WrapAroundR-fC1[i]<fdC1p[i]&&fC1[i]<WrapAroundR&&i<fN1)
         fdC1p[i]=WrapAroundR-fC1[i];
      if(WrapAroundR+fC1[i]<fdC1p[i]&&fC1[i]>-WrapAroundR&&i<fN1)
         fdC1m[i]=WrapAroundR+fC1[i];
   }
   double k=TaperH/(TaperW);
   double b=-(Radius-TaperW)*k;

   for(int i=0;i<fN;i++) {
      if(fC2[i]<=fC1[i]*k+b) {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
      if(fC2[i]<=-fC1[i]*k+b) {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
      if(fC2[i]-(fC1[i]*k+b)<fdC2p[i]) {
         fdC2m[i]=fC2[i]-(k*fC1[i]+b);
         fdC1p[i]=fC1[i]-b/k-fC2[i]/k;
      }
      if(fC2[i]-(-k*fC1[i]+b)<fdC2m[i]) {
         fdC2m[i]=fC2[i]-(-fC1[i]*k+b);
         fdC1m[i]=-fC1[i]/k-b/k-fC2[i];
      }
   }
   double x1=HoleTaperW,
          y1=Height,
          x2=HoleR,
          y2=Height-HoleTaperH,
          x3=Radius-CornerW,
          y3=Height,
          x4=Radius,
          y4=Height-CornerH;
   // y = k x + b
   double k1=(y1-y2)/(x1-x2);
   double b1=y1-k1*x1;
   double k2=(y3-y4)/(x3-x4);
   double b2=y3-k2*x3;

   for (int i=0;i<fN;i++) {
      if (x1!=x2) {
         //right side of hole taper
         if (fC1[i]-fC2[i]/k1+b1/k1<fdC1m[i] && fC2[i]>y2 &&
               fC1[i]-fC2[i]/k1+b1/k1>0)
            fdC1m[i]=fC1[i]-fC2[i]/k1+b1/k1;
         //left side of hole taper
         if (-fC1[i]-fC2[i]/k1+b1/k1>0
               &&-fC1[i]-fC2[i]/k1+b1/k1<fdC1p[i]&&fC2[i]>y2)
            fdC1p[i]=-fC1[i]-fC2[i]/k1+b1/k1;
      } else { //x1==x2
         //right side of hole taper
         if (fC1[i]-x1<fdC1m[i] && fC2[i]>y2 && fC1[i]-x1>0) fdC1m[i]=fC1[i]-x1;
         //left side of hole taper
         if (-fC1[i]-x1>0&&-fC1[i]-x1<fdC1p[i]&&fC2[i]>y2) fdC1p[i]=-fC1[i]-x1;
      }
      //right side of hole taper
      if (fC1[i]-HoleR<fdC1m[i] && fC2[i]>HoleH && fC1[i]-HoleR>0)
          fdC1m[i]=fC1[i]-HoleR;
      //left side of hole
      if (-fC1[i]-HoleR>0&&-fC1[i]-HoleR<fdC1p[i]&&fC2[i]>HoleH)
         fdC1p[i]=-fC1[i]-HoleR;
      //left corner
      if (fC1[i]+fC2[i]/k2-b2/k2>0 && fC1[i]+fC2[i]/k2-b2/k2<fdC1m[i] &&
            fC2[i]>y4) fdC1m[i]=fC1[i]+fC2[i]/k2-b2/k2;
      //right corner
      if (-fC1[i]+fC2[i]/k2-b2/k2>0
            &&-fC1[i]+fC2[i]/k2-b2/k2<fdC1p[i]&&fC2[i]>y4)
         fdC1p[i]=-fC1[i]+fC2[i]/k2-b2/k2;
      //down right side of hole
      if (-fC2[i]+fC1[i]*k1+b1>0&&-fC2[i]+fC1[i]*k1+b1<fdC2p[i]&&fC2[i]>y2)
         fdC2p[i]=-fC2[i]+fC1[i]*k1+b1;
      //down right of corner
      if (-fC2[i]-fC1[i]*k2+b2>0&&-fC2[i]-fC1[i]*k2+b2<fdC2p[i]&&fC2[i]>y4)
         fdC2p[i]=-fC2[i]-fC1[i]*k2+b2;
      //down left side of hole
      if (-fC2[i]-fC1[i]*k1+b1>0&&-fC2[i]-fC1[i]*k1+b1<fdC2p[i]&&fC2[i]>y2)
         fdC2p[i]=-fC2[i]-fC1[i]*k1+b1;
      //down left of corner
      if (-fC2[i]+fC1[i]*k2+b2>0&&-fC2[i]+fC1[i]*k2+b2<fdC2p[i]&&fC2[i]>y4)
         fdC2p[i]=-fC2[i]+fC1[i]*k2+b2;
      //down center of hole
      if (y2-fC2[i]<fdC2p[i]&&fC1[i]>-HoleR&&fC1[i]<HoleR)
         fdC2p[i]=y2-fC2[i];
   }
}
//_____________________________________________________________________________
//
void PointContactDZ::InitializeGrid()
{
   // we want no grid point right on z-axis
   if (fN1%2==1) {
      Error("InitializeGrid", "Number of points in D can't be odd! Abort.");
      abort();
   }

   if (WrapAroundR==-1)WrapAroundR=Radius;
   SetStepLength(2*Radius/(fN1-1),Height/(fN2-1));
   for(int i=fN;i-->0;) fC1[i]=fC1[i]-Radius;

   // set initial potential values
   for(int i=fN;i-->0;) {
      fV[i]=(V1+V0)/2;
      // set potential for inner electrodes
      if(fC1[i]>=-PointContactR && fC1[i]<=PointContactR
            && fC2[i]<=PointContactH) {
         fV[i]=V0;
         fIsFixed[i]=true;
      }
   }
   // set potential for outer electrodes
   for(int i=fN-1;i>=fN-fN1;i--) {
      fIsFixed[i]=true;
      fV[i]=V1;
   }
   for(int i=0;i<fN-fN1;i=i+fN1) {
      fIsFixed[i]=true;
      fIsFixed[i+fN1-1]=true;
      fV[i]=V1;
      fV[i+fN1-1]=V1;
   }
   for (int i=0;i<fN1;i++) {
      if(fC1[i]>=WrapAroundR||fC1[i]<=-WrapAroundR) {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
   }

   double x1=HoleR+HoleTaperW,
          y1=Height,
          x2=HoleR,
          y2=Height-HoleTaperH,
          x3=Radius-CornerW,
          y3=Height,
          x4=Radius,
          y4=Height-CornerH;
   double k1=(y1-y2)/(x1-x2);
   double b1=y1-k1*x1;
   double k2=(y3-y4)/(x3-x4);
   double b2=(y3-k2*x3);
   if(x3!=x4)
      for(int i=0;i<fN;i++) {
         if(fC2[i]>-k2*(fC1[i])+b2||(fC2[i]>k2*(fC1[i])+b2)) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }
   if(x1!=x2) {
      for (int i=0;i<fN;i++) {
         if(((fC2[i]>-k1*(fC1[i])+b1 && fC2[i]>y2))&&fC1[i]<0) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
         if(((fC2[i]>k1*(fC1[i])+b1 && fC2[i]>y2))&&fC1[i]>0) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }
   } else { //x1==x2
      for (int i=0;i<fN;i++) {
         if(fC1[i]<=x1&&fC1[i]>=-x1&&fC2[i]>=y2) {
            fIsFixed[i]=true;
            fV[i]=V1;
         }
      }
   }
   for (int i=0;i<fN;i++) {
      if(fC1[i]<=HoleR&&fC1[i]>=-HoleR&&fC2[i]>=Height-HoleH) {
         fIsFixed[i]=true;
         fV[i]=V1;
      }
   }
   SetBoundary();
}
//_____________________________________________________________________________
//
#include <cmath>
#include <fstream>
using namespace std;
void PointContactDZ::Export2fieldgen(const char *output)
{
   ofstream file(output);
   file<<"# xtal_length "<<Height/mm<<endl;
   file<<"# xtal_radius "<<Radius/mm<<endl;
   file<<"# pc_length   "<<PointContactH/mm<<endl;
   file<<"# pc_radius   "<<PointContactR/mm<<endl;
   file<<"# taper_length "<<TaperH/mm<<endl;
   file<<"# wrap_around_radius "<<WrapAroundR/mm<<endl;
   file<<"# ditch_depth "<<GrooveH/mm<<endl;
   file<<"# ditch_thickness "<<GrooveW/mm<<endl;
   file<<"# xtal_grid "<<fdC1p[0]/mm<<endl;
   file<<"# impurity_z0 "<<fImpurity[0]*cm3<<endl;
   file<<"# impurity_gradient "
      <<(fImpurity[fN-1]-fImpurity[0])/fdC2p[0]*cm*cm3<<endl;
   file<<"# xtal_HV      "<<abs(V0-V1)/volt<<endl;
   file<<"# max_iterations "<<GetNsor()<<endl;
   file<<"#"<<endl;
   file<<"## r (mm), z (mm), V (V),  E (V/cm), E_r (V/cm), E_z (V/cm)"<<endl;
   for (int i=0;i<fN;i++) file<<fC1[i]<<" "<<fC2[i]<<" "<<fV[i]<<" "
      <<sqrt(fE1[i]*fE1[i]+fE2[i]*fE2[i])<<" "<<fE1[i]<<" "<<fE2[i]<<endl;
   file.close();
}
//_____________________________________________________________________________
//
void PointContactDZ::SetGridImpurity()
{
   X::SetGridImpurity();

   if (TaperW+WrapAroundR>Radius) {
      Error("SetGridImpurity", "TaperW(%.1fmm) + WrapAroundR(%.1fmm)"
            " > Radiu(%.1fmm). Abort!", TaperW/mm, WrapAroundR/mm, Radius/mm);
      abort();
   } else if (WrapAroundR-GrooveW<PointContactR) {
      Error("SetGridImpurity", "WrapAroundR(%.1fmm) - GrooveW(%.1fmm)"
            " < PointContactR(%.1fmm). Abort!",
            WrapAroundR/mm, GrooveW/mm, PointContactR/mm);
      abort();
   } else {
      for (int i=0; i<fN; i++) {
         if (((fC1[i]>WrapAroundR-GrooveW && fC1[i]<WrapAroundR) ||
                  (fC1[i]>-WrapAroundR && fC1[i]<-WrapAroundR+GrooveW))
               && fC2[i]<GrooveH) fImpurity[i]=0;
      }
   }
}
//_____________________________________________________________________________
//
double PointContactDZ::GetData(double x, double y, double z, double *data)
{
   //if (point in boundary) return V1;
   return XY::GetData(x,y,z,data);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct ListNode
{
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(NULL){}
};

ListNode* mergeKLists(vector<ListNode*> &lists)
{
    int n = lists.size();
    if (n == 0) return NULL;
    if (n == 1) return lists[0];

    vector<ListNode*> p(n);
    for (int i = 0; i < n; ++i)
    {
        p[i] = lists[i];
    }

    ListNode* head = NULL;
    ListNode* cur = NULL;

    while (true)
    {
        // point to the first Not NULL node, pivot
        ListNode* minP = new ListNode(1000000000);
        int minI = -1;
        for (int i = 0; i < n; ++i)
        {
            if (p[i] != NULL && p[i]->val < minP->val)
            {
                minP = p[i];
                minI = i;
            }
        }

        // all list are empty, terminate loop
        if (minI == -1) break;

        // minP ponit to the min node

        if (cur == NULL)
        {
            head = minP;
            cur = minP;
        }
        else
        {
            cur->next = minP;
            cur = minP;         // update current point
        }
        p[minI] = p[minI]->next;
    }

    return head;
}

int main()
{
    vector<ListNode*> lists(3);
    lists[0] = new ListNode(1);
    lists[0]->next = new ListNode(3);
    lists[0]->next->next = new ListNode(7);

    lists[1] = new ListNode(2);
    lists[1]->next = new ListNode(6);
    lists[1]->next->next = new ListNode(9);

    lists[2] = new ListNode(5);
    lists[2]->next = new ListNode(8);
    lists[2]->next->next = new ListNode(10);

    ListNode* head = mergeKLists(lists);
    for (ListNode* p = head; p != NULL; p = p->next)
    {
        cout << " " << p->val;
    }
    cout << endl;
    return 0;
}
<commit_msg>k-way merge using minHeap (STL prioprity_queue, greater<int>), good, need recheck<commit_after>#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <utility>
#include <cstdio>
#include <cstdlib>
using namespace std;

struct ListNode
{
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};

ListNode *mergeKLists(vector<ListNode *> &lists)
{
	ListNode* newList = NULL;
	ListNode* preNode = NULL;

	priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > minHeap;

	int n = lists.size();

	// push the first n elements into a Min-Heap
	int k = 0;
	for (int i = 0; i < n; ++i)
	{
		if (lists[i] != NULL) k++;
	}
	if (k == 0) return NULL;

	// Construct a min-Heap with the head-K elements
	for (int i = 0; i < n; ++i)
	{
		if (lists[i] != NULL)
		{
			minHeap.push(make_pair(lists[i]->val, i));
		}
	}

	// remove the min element, and insert to the answer list
	// until the heap is empty
	while (minHeap.size() > 0)
	{
		// pop the minimum element
		auto tmp = minHeap.top();
		minHeap.pop();

		// insert it into the answer list
		ListNode* pNewNode = new ListNode(tmp.first);
		if (preNode != NULL)
		{
			preNode->next = pNewNode;
			preNode = pNewNode;
		}
		else
		{
			newList = pNewNode;
			preNode = pNewNode;
		}

		// the pointer move to next
		lists[tmp.second] = lists[tmp.second]->next;
		// if not NULL, push the next element into heap so that
		// the heap size is still k
		// else not push element, the heap size is k - 1
		if (lists[tmp.second] != NULL)
		{
			minHeap.push(make_pair(lists[tmp.second]->val, tmp.second));
			//cout << "push:" << lists[tmp.second]->val << endl;
		}
	}

	return newList;
}

int main()
{
	ListNode* L1 = new ListNode(1);
	L1->next = new ListNode(2);
	L1->next->next = new ListNode(3);

	ListNode* L2 = new ListNode(4);
	L2->next = new ListNode(5);
	L2->next->next = new ListNode(6);

	vector<ListNode*> v;
	v.push_back(L1);
	v.push_back(L2);

	ListNode* ans = mergeKLists(v);
}<|endoftext|>


<commit_before>/*
   Copyright (C) 2018 Alexandr Akulich <akulichalexander@gmail.com>

   This file is a part of TelegramQt library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

 */

#ifndef TELEGRAM_CONNECTION_ERROR_HPP
#define TELEGRAM_CONNECTION_ERROR_HPP

#include "telegramqt_global.h"

#include <QObject>
#include <QByteArray>

namespace Telegram {

class TELEGRAMQT_EXPORT ConnectionError
{
    Q_GADGET
public:
    enum Code : qint32 {
        InvalidAuthKey = -404, // 6cfeffff in network byte order, Auth key id is not found in the server DB
    };
    Q_ENUM(Code)

    ConnectionError() = default;
    explicit ConnectionError(const QByteArray &data);
    explicit ConnectionError(const qint32 code);

    static constexpr int packageSize() { return 4; }

    Q_REQUIRED_RESULT Code code() const;
    Q_REQUIRED_RESULT QByteArray toByteArray() const;
    Q_REQUIRED_RESULT QString description() const;

private:
    qint32 m_code = 0;
};

} // Telegram namespace

#endif // TELEGRAM_CONNECTION_ERROR_HPP
<commit_msg>ConnectionError: Add Flood error<commit_after>/*
   Copyright (C) 2018 Alexandr Akulich <akulichalexander@gmail.com>

   This file is a part of TelegramQt library.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

 */

#ifndef TELEGRAM_CONNECTION_ERROR_HPP
#define TELEGRAM_CONNECTION_ERROR_HPP

#include "telegramqt_global.h"

#include <QObject>
#include <QByteArray>

namespace Telegram {

class TELEGRAMQT_EXPORT ConnectionError
{
    Q_GADGET
public:
    enum Code : qint32 {
        InvalidAuthKey = -404, // 6cfeffff in network byte order, Auth key id is not found in the server DB
        Flood = -429,
    };
    Q_ENUM(Code)

    ConnectionError() = default;
    explicit ConnectionError(const QByteArray &data);
    explicit ConnectionError(const qint32 code);

    static constexpr int packageSize() { return 4; }

    Q_REQUIRED_RESULT Code code() const;
    Q_REQUIRED_RESULT QByteArray toByteArray() const;
    Q_REQUIRED_RESULT QString description() const;

private:
    qint32 m_code = 0;
};

} // Telegram namespace

#endif // TELEGRAM_CONNECTION_ERROR_HPP
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Authors: Oystein Djuvsland <oysteind@ift.uib.no>                       *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliHLTPHOSRecoParamHandler.h"
#include "AliCDBManager.h"
#include "AliCDBEntry.h"
#include "AliPHOSRecoParam.h"
#include "TMatrixF.h"
#include "TVector3.h"
#include "AliPHOSPIDv1.h"
#include "TObjArray.h"

AliHLTPHOSRecoParamHandler::AliHLTPHOSRecoParamHandler() :
AliHLTCaloRecoParamHandler("PHOS")
,fPHOSPidPtr(0)
{
   // See header file for class documentation

   fPHOSPidPtr = new AliPHOSPIDv1();

}

AliHLTPHOSRecoParamHandler::~AliHLTPHOSRecoParamHandler()
{
   // See header file for class documentation
}

Float_t AliHLTPHOSRecoParamHandler::GetCorrectedEnergy ( Float_t e )
{
   // See header file for class documentation
  //   return fPHOSPidPtr->GetCalibratedEnergy(e); //WHY?
   return e;
}

void AliHLTPHOSRecoParamHandler::FillParameters()
{
   //See header file for class documentation
   if(fRecoParamPtr)
   {
      fLogWeight = dynamic_cast<AliPHOSRecoParam*>(fRecoParamPtr)->GetEMCLogWeight();
      fRecPointMemberThreshold = dynamic_cast<AliPHOSRecoParam*>(fRecoParamPtr)->GetEMCMinE();
      fRecPointThreshold = dynamic_cast<AliPHOSRecoParam*>(fRecoParamPtr)->GetEMCClusteringThreshold();
   }
}

<commit_msg>- added energy correction from AliPHOSPIDv1<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Authors: Oystein Djuvsland <oysteind@ift.uib.no>                       *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliHLTPHOSRecoParamHandler.h"
#include "AliCDBManager.h"
#include "AliCDBEntry.h"
#include "AliPHOSRecoParam.h"
#include "TMatrixF.h"
#include "TVector3.h"
#include "AliPHOSPIDv1.h"
#include "TObjArray.h"

AliHLTPHOSRecoParamHandler::AliHLTPHOSRecoParamHandler() :
AliHLTCaloRecoParamHandler("PHOS")
,fPHOSPidPtr(0)
{
   // See header file for class documentation

   fPHOSPidPtr = new AliPHOSPIDv1();

}

AliHLTPHOSRecoParamHandler::~AliHLTPHOSRecoParamHandler()
{
   // See header file for class documentation
}

Float_t AliHLTPHOSRecoParamHandler::GetCorrectedEnergy ( Float_t e )
{
   // See header file for class documentation
   return fPHOSPidPtr->GetCalibratedEnergy(e);
}

void AliHLTPHOSRecoParamHandler::FillParameters()
{
   //See header file for class documentation
   if(fRecoParamPtr)
   {
      fLogWeight = dynamic_cast<AliPHOSRecoParam*>(fRecoParamPtr)->GetEMCLogWeight();
      fRecPointMemberThreshold = dynamic_cast<AliPHOSRecoParam*>(fRecoParamPtr)->GetEMCMinE();
      fRecPointThreshold = dynamic_cast<AliPHOSRecoParam*>(fRecoParamPtr)->GetEMCClusteringThreshold();
   }
}

<|endoftext|>


<commit_before>//===- LazyValueInfo.cpp - Value constraint analysis ----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the interface for lazy computation of value constraint
// information.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "lazy-value-info"
#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
using namespace llvm;

char LazyValueInfo::ID = 0;
static RegisterPass<LazyValueInfo>
X("lazy-value-info", "Lazy Value Information Analysis", false, true);

namespace llvm {
  FunctionPass *createLazyValueInfoPass() { return new LazyValueInfo(); }
}

//===----------------------------------------------------------------------===//
//                               LVILatticeVal
//===----------------------------------------------------------------------===//

/// LVILatticeVal - This is the information tracked by LazyValueInfo for each
/// value.
///
/// FIXME: This is basically just for bringup, this can be made a lot more rich
/// in the future.
///
namespace {
class LVILatticeVal {
  enum LatticeValueTy {
    /// undefined - This LLVM Value has no known value yet.
    undefined,
    /// constant - This LLVM Value has a specific constant value.
    constant,

    /// notconstant - This LLVM value is known to not have the specified value.
    notconstant,

    /// overdefined - This instruction is not known to be constant, and we know
    /// it has a value.
    overdefined
  };

  /// Val: This stores the current lattice value along with the Constant* for
  /// the constant if this is a 'constant' or 'notconstant' value.
  PointerIntPair<Constant *, 2, LatticeValueTy> Val;

public:
  LVILatticeVal() : Val(0, undefined) {}

  static LVILatticeVal get(Constant *C) {
    LVILatticeVal Res;
    Res.markConstant(C);
    return Res;
  }
  static LVILatticeVal getNot(Constant *C) {
    LVILatticeVal Res;
    Res.markNotConstant(C);
    return Res;
  }

  bool isUndefined() const   { return Val.getInt() == undefined; }
  bool isConstant() const    { return Val.getInt() == constant; }
  bool isNotConstant() const { return Val.getInt() == notconstant; }
  bool isOverdefined() const { return Val.getInt() == overdefined; }

  Constant *getConstant() const {
    assert(isConstant() && "Cannot get the constant of a non-constant!");
    return Val.getPointer();
  }

  Constant *getNotConstant() const {
    assert(isNotConstant() && "Cannot get the constant of a non-notconstant!");
    return Val.getPointer();
  }

  /// markOverdefined - Return true if this is a change in status.
  bool markOverdefined() {
    if (isOverdefined())
      return false;
    Val.setInt(overdefined);
    return true;
  }

  /// markConstant - Return true if this is a change in status.
  bool markConstant(Constant *V) {
    if (isConstant()) {
      assert(getConstant() == V && "Marking constant with different value");
      return false;
    }

    assert(isUndefined());
    Val.setInt(constant);
    assert(V && "Marking constant with NULL");
    Val.setPointer(V);
    return true;
  }

  /// markNotConstant - Return true if this is a change in status.
  bool markNotConstant(Constant *V) {
    if (isNotConstant()) {
      assert(getNotConstant() == V && "Marking !constant with different value");
      return false;
    }

    if (isConstant())
      assert(getConstant() != V && "Marking not constant with different value");
    else
      assert(isUndefined());

    Val.setInt(notconstant);
    assert(V && "Marking constant with NULL");
    Val.setPointer(V);
    return true;
  }

  /// mergeIn - Merge the specified lattice value into this one, updating this
  /// one and returning true if anything changed.
  bool mergeIn(const LVILatticeVal &RHS) {
    if (RHS.isUndefined() || isOverdefined()) return false;
    if (RHS.isOverdefined()) return markOverdefined();

    if (RHS.isNotConstant()) {
      if (isNotConstant()) {
        if (getNotConstant() != RHS.getNotConstant() ||
            isa<ConstantExpr>(getNotConstant()) ||
            isa<ConstantExpr>(RHS.getNotConstant()))
          return markOverdefined();
        return false;
      }
      if (isConstant()) {
        if (getConstant() == RHS.getNotConstant() ||
            isa<ConstantExpr>(RHS.getNotConstant()) ||
            isa<ConstantExpr>(getConstant()))
          return markOverdefined();
        return markNotConstant(RHS.getNotConstant());
      }

      assert(isUndefined() && "Unexpected lattice");
      return markNotConstant(RHS.getNotConstant());
    }

    // RHS must be a constant, we must be undef, constant, or notconstant.
    if (isUndefined())
      return markConstant(RHS.getConstant());

    if (isConstant()) {
      if (getConstant() != RHS.getConstant())
        return markOverdefined();
      return false;
    }

    // If we are known "!=4" and RHS is "==5", stay at "!=4".
    if (getNotConstant() == RHS.getConstant() ||
        isa<ConstantExpr>(getNotConstant()) ||
        isa<ConstantExpr>(RHS.getConstant()))
      return markOverdefined();
    return false;
  }

};

} // end anonymous namespace.

namespace llvm {
raw_ostream &operator<<(raw_ostream &OS, const LVILatticeVal &Val) {
  if (Val.isUndefined())
    return OS << "undefined";
  if (Val.isOverdefined())
    return OS << "overdefined";

  if (Val.isNotConstant())
    return OS << "notconstant<" << *Val.getNotConstant() << '>';
  return OS << "constant<" << *Val.getConstant() << '>';
}
}

//===----------------------------------------------------------------------===//
//                            LazyValueInfo Impl
//===----------------------------------------------------------------------===//

bool LazyValueInfo::runOnFunction(Function &F) {
  TD = getAnalysisIfAvailable<TargetData>();
  // Fully lazy.
  return false;
}

void LazyValueInfo::releaseMemory() {
  // No caching yet.
}

static LVILatticeVal GetValueInBlock(Value *V, BasicBlock *BB,
                                     DenseMap<BasicBlock*, LVILatticeVal> &);

static LVILatticeVal GetValueOnEdge(Value *V, BasicBlock *BBFrom,
                                    BasicBlock *BBTo,
                              DenseMap<BasicBlock*, LVILatticeVal> &BlockVals) {
  // FIXME: Pull edge logic out of jump threading.

  if (BranchInst *BI = dyn_cast<BranchInst>(BBFrom->getTerminator())) {
    // If this is a conditional branch and only one successor goes to BBTo, then
    // we maybe able to infer something from the condition.
    if (BI->isConditional() &&
        BI->getSuccessor(0) != BI->getSuccessor(1)) {
      bool isTrueDest = BI->getSuccessor(0) == BBTo;
      assert(BI->getSuccessor(!isTrueDest) == BBTo &&
             "BBTo isn't a successor of BBFrom");

      // If V is the condition of the branch itself, then we know exactly what
      // it is.
      if (BI->getCondition() == V)
        return LVILatticeVal::get(ConstantInt::get(
                                 Type::getInt1Ty(V->getContext()), isTrueDest));

      // If the condition of the branch is an equality comparison, we may be
      // able to infer the value.
      if (ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition()))
        if (ICI->isEquality() && ICI->getOperand(0) == V &&
            isa<Constant>(ICI->getOperand(1))) {
          // We know that V has the RHS constant if this is a true SETEQ or
          // false SETNE.
          if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ))
            return LVILatticeVal::get(cast<Constant>(ICI->getOperand(1)));
          return LVILatticeVal::getNot(cast<Constant>(ICI->getOperand(1)));
        }
    }
  }

  // TODO: Info from switch.

  // Otherwise see if the value is known in the block.
  return GetValueInBlock(V, BBFrom, BlockVals);
}

static LVILatticeVal GetValueInBlock(Value *V, BasicBlock *BB,
                              DenseMap<BasicBlock*, LVILatticeVal> &BlockVals) {
  // See if we already have a value for this block.
  LVILatticeVal &BBLV = BlockVals[BB];

  // If we've already computed this block's value, return it.
  if (!BBLV.isUndefined())
    return BBLV;

  // Otherwise, this is the first time we're seeing this block.  Reset the
  // lattice value to overdefined, so that cycles will terminate and be
  // conservatively correct.
  BBLV.markOverdefined();

  LVILatticeVal Result;  // Start Undefined.

  // If V is live in to BB, see if our predecessors know anything about it.
  Instruction *BBI = dyn_cast<Instruction>(V);
  if (BBI == 0 || BBI->getParent() != BB) {
    unsigned NumPreds = 0;

    // Loop over all of our predecessors, merging what we know from them into
    // result.
    for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
      Result.mergeIn(GetValueOnEdge(V, *PI, BB, BlockVals));

      // If we hit overdefined, exit early.  The BlockVals entry is already set
      // to overdefined.
      if (Result.isOverdefined())
        return Result;
      ++NumPreds;
    }

    // If this is the entry block, we must be asking about an argument.  The
    // value is overdefined.
    if (NumPreds == 0 && BB == &BB->getParent()->front()) {
      assert(isa<Argument>(V) && "Unknown live-in to the entry block");
      Result.markOverdefined();
      return Result;
    }

    // Return the merged value, which is more precise than 'overdefined'.
    assert(!Result.isOverdefined());
    return BlockVals[BB] = Result;
  }

  // If this value is defined by an instruction in this block, we have to
  // process it here somehow or return overdefined.
  if (PHINode *PN = dyn_cast<PHINode>(BBI)) {
    (void)PN;
    // TODO: PHI Translation in preds.
  } else {

  }

  Result.markOverdefined();
  return BlockVals[BB] = Result;
}

Constant *LazyValueInfo::getConstant(Value *V, BasicBlock *BB) {
  // If already a constant, return it.
  if (Constant *VC = dyn_cast<Constant>(V))
    return VC;

  DenseMap<BasicBlock*, LVILatticeVal> BlockValues;

  DEBUG(errs() << "Getting value " << *V << " at end of block '"
               << BB->getName() << "'\n");
  LVILatticeVal Result = GetValueInBlock(V, BB, BlockValues);

  DEBUG(errs() << "  Result = " << Result << "\n");

  if (Result.isConstant())
    return Result.getConstant();
  return 0;
}

/// getConstantOnEdge - Determine whether the specified value is known to be a
/// constant on the specified edge.  Return null if not.
Constant *LazyValueInfo::getConstantOnEdge(Value *V, BasicBlock *FromBB,
                                           BasicBlock *ToBB) {
  // If already a constant, return it.
  if (Constant *VC = dyn_cast<Constant>(V))
    return VC;

  DenseMap<BasicBlock*, LVILatticeVal> BlockValues;

  DEBUG(errs() << "Getting value " << *V << " on edge from '"
               << FromBB->getName() << "' to '" << ToBB->getName() << "'\n");
  LVILatticeVal Result = GetValueOnEdge(V, FromBB, ToBB, BlockValues);

  DEBUG(errs() << "  Result = " << Result << "\n");

  if (Result.isConstant())
    return Result.getConstant();
  return 0;
}

/// getPredicateOnEdge - Determine whether the specified value comparison
/// with a constant is known to be true or false on the specified CFG edge.
/// Pred is a CmpInst predicate.
LazyValueInfo::Tristate
LazyValueInfo::getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
                                  BasicBlock *FromBB, BasicBlock *ToBB) {
  LVILatticeVal Result;

  // If already a constant, we can use constant folding.
  if (Constant *VC = dyn_cast<Constant>(V)) {
    Result = LVILatticeVal::get(VC);
  } else {
    DenseMap<BasicBlock*, LVILatticeVal> BlockValues;

    DEBUG(errs() << "Getting value " << *V << " on edge from '"
          << FromBB->getName() << "' to '" << ToBB->getName() << "'\n");
    Result = GetValueOnEdge(V, FromBB, ToBB, BlockValues);
    DEBUG(errs() << "  Result = " << Result << "\n");
  }

  // If we know the value is a constant, evaluate the conditional.
  Constant *Res = 0;
  if (Result.isConstant()) {
    Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, TD);
    if (ConstantInt *ResCI = dyn_cast_or_null<ConstantInt>(Res))
      return ResCI->isZero() ? False : True;
  } else if (Result.isNotConstant()) {
    // If this is an equality comparison, we can try to fold it knowing that
    // "V != C1".
    if (Pred == ICmpInst::ICMP_EQ) {
      // !C1 == C -> false iff C1 == C.
      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
                                            Result.getNotConstant(), C, TD);
      if (Res->isNullValue())
        return False;
    } else if (Pred == ICmpInst::ICMP_NE) {
      // !C1 != C -> true iff C1 == C.
      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_EQ,
                                            Result.getNotConstant(), C, TD);
      if (Res->isNullValue())
        return True;
    }
  }

  return Unknown;
}

<commit_msg>refactor a bunch of code forming the new LazyValueInfoCache and LVIQuery classes, no functionality change.<commit_after>//===- LazyValueInfo.cpp - Value constraint analysis ----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the interface for lazy computation of value constraint
// information.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "lazy-value-info"
#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
using namespace llvm;

char LazyValueInfo::ID = 0;
static RegisterPass<LazyValueInfo>
X("lazy-value-info", "Lazy Value Information Analysis", false, true);

namespace llvm {
  FunctionPass *createLazyValueInfoPass() { return new LazyValueInfo(); }
}

//===----------------------------------------------------------------------===//
//                               LVILatticeVal
//===----------------------------------------------------------------------===//

/// LVILatticeVal - This is the information tracked by LazyValueInfo for each
/// value.
///
/// FIXME: This is basically just for bringup, this can be made a lot more rich
/// in the future.
///
namespace {
class LVILatticeVal {
  enum LatticeValueTy {
    /// undefined - This LLVM Value has no known value yet.
    undefined,
    /// constant - This LLVM Value has a specific constant value.
    constant,

    /// notconstant - This LLVM value is known to not have the specified value.
    notconstant,

    /// overdefined - This instruction is not known to be constant, and we know
    /// it has a value.
    overdefined
  };

  /// Val: This stores the current lattice value along with the Constant* for
  /// the constant if this is a 'constant' or 'notconstant' value.
  PointerIntPair<Constant *, 2, LatticeValueTy> Val;

public:
  LVILatticeVal() : Val(0, undefined) {}

  static LVILatticeVal get(Constant *C) {
    LVILatticeVal Res;
    Res.markConstant(C);
    return Res;
  }
  static LVILatticeVal getNot(Constant *C) {
    LVILatticeVal Res;
    Res.markNotConstant(C);
    return Res;
  }

  bool isUndefined() const   { return Val.getInt() == undefined; }
  bool isConstant() const    { return Val.getInt() == constant; }
  bool isNotConstant() const { return Val.getInt() == notconstant; }
  bool isOverdefined() const { return Val.getInt() == overdefined; }

  Constant *getConstant() const {
    assert(isConstant() && "Cannot get the constant of a non-constant!");
    return Val.getPointer();
  }

  Constant *getNotConstant() const {
    assert(isNotConstant() && "Cannot get the constant of a non-notconstant!");
    return Val.getPointer();
  }

  /// markOverdefined - Return true if this is a change in status.
  bool markOverdefined() {
    if (isOverdefined())
      return false;
    Val.setInt(overdefined);
    return true;
  }

  /// markConstant - Return true if this is a change in status.
  bool markConstant(Constant *V) {
    if (isConstant()) {
      assert(getConstant() == V && "Marking constant with different value");
      return false;
    }

    assert(isUndefined());
    Val.setInt(constant);
    assert(V && "Marking constant with NULL");
    Val.setPointer(V);
    return true;
  }

  /// markNotConstant - Return true if this is a change in status.
  bool markNotConstant(Constant *V) {
    if (isNotConstant()) {
      assert(getNotConstant() == V && "Marking !constant with different value");
      return false;
    }

    if (isConstant())
      assert(getConstant() != V && "Marking not constant with different value");
    else
      assert(isUndefined());

    Val.setInt(notconstant);
    assert(V && "Marking constant with NULL");
    Val.setPointer(V);
    return true;
  }

  /// mergeIn - Merge the specified lattice value into this one, updating this
  /// one and returning true if anything changed.
  bool mergeIn(const LVILatticeVal &RHS) {
    if (RHS.isUndefined() || isOverdefined()) return false;
    if (RHS.isOverdefined()) return markOverdefined();

    if (RHS.isNotConstant()) {
      if (isNotConstant()) {
        if (getNotConstant() != RHS.getNotConstant() ||
            isa<ConstantExpr>(getNotConstant()) ||
            isa<ConstantExpr>(RHS.getNotConstant()))
          return markOverdefined();
        return false;
      }
      if (isConstant()) {
        if (getConstant() == RHS.getNotConstant() ||
            isa<ConstantExpr>(RHS.getNotConstant()) ||
            isa<ConstantExpr>(getConstant()))
          return markOverdefined();
        return markNotConstant(RHS.getNotConstant());
      }

      assert(isUndefined() && "Unexpected lattice");
      return markNotConstant(RHS.getNotConstant());
    }

    // RHS must be a constant, we must be undef, constant, or notconstant.
    if (isUndefined())
      return markConstant(RHS.getConstant());

    if (isConstant()) {
      if (getConstant() != RHS.getConstant())
        return markOverdefined();
      return false;
    }

    // If we are known "!=4" and RHS is "==5", stay at "!=4".
    if (getNotConstant() == RHS.getConstant() ||
        isa<ConstantExpr>(getNotConstant()) ||
        isa<ConstantExpr>(RHS.getConstant()))
      return markOverdefined();
    return false;
  }

};

} // end anonymous namespace.

namespace llvm {
raw_ostream &operator<<(raw_ostream &OS, const LVILatticeVal &Val) {
  if (Val.isUndefined())
    return OS << "undefined";
  if (Val.isOverdefined())
    return OS << "overdefined";

  if (Val.isNotConstant())
    return OS << "notconstant<" << *Val.getNotConstant() << '>';
  return OS << "constant<" << *Val.getConstant() << '>';
}
}

//===----------------------------------------------------------------------===//
//                          LazyValueInfoCache Decl
//===----------------------------------------------------------------------===//

namespace {
  /// LazyValueInfoCache - This is the cache kept by LazyValueInfo which
  /// maintains information about queries across the clients' queries.
  class LazyValueInfoCache {
  public:
    /// BlockCacheEntryTy - This is a computed lattice value at the end of the
    /// specified basic block for a Value* that depends on context.
    typedef std::pair<BasicBlock*, LVILatticeVal> BlockCacheEntryTy;

    /// ValueCacheEntryTy - This is all of the cached block information for
    /// exactly one Value*.  The entries are sorted by the BasicBlock* of the
    /// entries, allowing us to do a lookup with a binary search.
    typedef std::vector<BlockCacheEntryTy> ValueCacheEntryTy;

  private:
    /// ValueCache - This is all of the cached information for all values,
    /// mapped from Value* to key information.
    DenseMap<Value*, ValueCacheEntryTy> ValueCache;
  public:

    /// getValueInBlock - This is the query interface to determine the lattice
    /// value for the specified Value* at the end of the specified block.
    LVILatticeVal getValueInBlock(Value *V, BasicBlock *BB);

    /// getValueOnEdge - This is the query interface to determine the lattice
    /// value for the specified Value* that is true on the specified edge.
    LVILatticeVal getValueOnEdge(Value *V, BasicBlock *FromBB,BasicBlock *ToBB);
  };
} // end anonymous namespace

//===----------------------------------------------------------------------===//
//                              LVIQuery Impl
//===----------------------------------------------------------------------===//

namespace {
  /// LVIQuery - This is a transient object that exists while a query is
  /// being performed.
  class LVIQuery {
    typedef LazyValueInfoCache::BlockCacheEntryTy BlockCacheEntryTy;
    typedef LazyValueInfoCache::ValueCacheEntryTy ValueCacheEntryTy;

    /// This is the current value being queried.
    Value *Val;

    /// This is all of the cached information about this value.
    ValueCacheEntryTy &Cache;

    /// BlockVals Temporary Cache used while processing a query.
    DenseMap<BasicBlock*, LVILatticeVal> BlockVals;

  public:

    LVIQuery(Value *V, ValueCacheEntryTy &VC) : Val(V), Cache(VC) {
    }

    LVILatticeVal getBlockValue(BasicBlock *BB);

    LVILatticeVal getEdgeValue(BasicBlock *FromBB, BasicBlock *ToBB);
  };
} // end anonymous namespace

LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) {
  // See if we already have a value for this block.
  LVILatticeVal &BBLV = BlockVals[BB];

  // If we've already computed this block's value, return it.
  if (!BBLV.isUndefined())
    return BBLV;

  // Otherwise, this is the first time we're seeing this block.  Reset the
  // lattice value to overdefined, so that cycles will terminate and be
  // conservatively correct.
  BBLV.markOverdefined();

  // If V is live into BB, see if our predecessors know anything about it.
  Instruction *BBI = dyn_cast<Instruction>(Val);
  if (BBI == 0 || BBI->getParent() != BB) {
    LVILatticeVal Result;  // Start Undefined.
    unsigned NumPreds = 0;

    // Loop over all of our predecessors, merging what we know from them into
    // result.
    for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
      Result.mergeIn(getEdgeValue(*PI, BB));

      // If we hit overdefined, exit early.  The BlockVals entry is already set
      // to overdefined.
      if (Result.isOverdefined())
        return Result;
      ++NumPreds;
    }

    // If this is the entry block, we must be asking about an argument.  The
    // value is overdefined.
    if (NumPreds == 0 && BB == &BB->getParent()->front()) {
      assert(isa<Argument>(Val) && "Unknown live-in to the entry block");
      Result.markOverdefined();
      return Result;
    }

    // Return the merged value, which is more precise than 'overdefined'.
    assert(!Result.isOverdefined());
    return BlockVals[BB] = Result;
  }

  // If this value is defined by an instruction in this block, we have to
  // process it here somehow or return overdefined.
  if (PHINode *PN = dyn_cast<PHINode>(BBI)) {
    (void)PN;
    // TODO: PHI Translation in preds.
  } else {

  }

  LVILatticeVal Result;
  Result.markOverdefined();
  return BlockVals[BB] = Result;
}

/// getEdgeValue - This method
LVILatticeVal LVIQuery::getEdgeValue(BasicBlock *BBFrom, BasicBlock *BBTo) {
  if (BranchInst *BI = dyn_cast<BranchInst>(BBFrom->getTerminator())) {
    // If this is a conditional branch and only one successor goes to BBTo, then
    // we maybe able to infer something from the condition.
    if (BI->isConditional() &&
        BI->getSuccessor(0) != BI->getSuccessor(1)) {
      bool isTrueDest = BI->getSuccessor(0) == BBTo;
      assert(BI->getSuccessor(!isTrueDest) == BBTo &&
             "BBTo isn't a successor of BBFrom");

      // If V is the condition of the branch itself, then we know exactly what
      // it is.
      if (BI->getCondition() == Val)
        return LVILatticeVal::get(ConstantInt::get(
                               Type::getInt1Ty(Val->getContext()), isTrueDest));

      // If the condition of the branch is an equality comparison, we may be
      // able to infer the value.
      if (ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition()))
        if (ICI->isEquality() && ICI->getOperand(0) == Val &&
            isa<Constant>(ICI->getOperand(1))) {
          // We know that V has the RHS constant if this is a true SETEQ or
          // false SETNE.
          if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ))
            return LVILatticeVal::get(cast<Constant>(ICI->getOperand(1)));
          return LVILatticeVal::getNot(cast<Constant>(ICI->getOperand(1)));
        }
    }
  }

  // TODO: Info from switch.

  // TODO: Handle more complex conditionals.  If (v == 0 || v2 < 1) is false, we
  // know that v != 0.

  // Otherwise see if the value is known in the block.
  return getBlockValue(BBFrom);
}

//===----------------------------------------------------------------------===//
//                         LazyValueInfoCache Impl
//===----------------------------------------------------------------------===//

LVILatticeVal LazyValueInfoCache::getValueInBlock(Value *V, BasicBlock *BB) {
  // If already a constant, there is nothing to compute.
  if (Constant *VC = dyn_cast<Constant>(V))
    return LVILatticeVal::get(VC);

  DEBUG(errs() << "Getting value " << *V << " at end of block '"
        << BB->getName() << "'\n");

  LVILatticeVal Result = LVIQuery(V, ValueCache[V]).getBlockValue(BB);

  DEBUG(errs() << "  Result = " << Result << "\n");
  return Result;
}

LVILatticeVal LazyValueInfoCache::
getValueOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB) {
  // If already a constant, there is nothing to compute.
  if (Constant *VC = dyn_cast<Constant>(V))
    return LVILatticeVal::get(VC);

  DEBUG(errs() << "Getting value " << *V << " on edge from '"
        << FromBB->getName() << "' to '" << ToBB->getName() << "'\n");
  LVILatticeVal Result =
    LVIQuery(V, ValueCache[V]).getEdgeValue(FromBB, ToBB);

  DEBUG(errs() << "  Result = " << Result << "\n");

  return Result;
}

//===----------------------------------------------------------------------===//
//                            LazyValueInfo Impl
//===----------------------------------------------------------------------===//

bool LazyValueInfo::runOnFunction(Function &F) {
  TD = getAnalysisIfAvailable<TargetData>();
  // Fully lazy.
  return false;
}

/// getCache - This lazily constructs the LazyValueInfoCache.
static LazyValueInfoCache &getCache(void *&PImpl) {
  if (!PImpl)
    PImpl = new LazyValueInfoCache();
  return *static_cast<LazyValueInfoCache*>(PImpl);
}

void LazyValueInfo::releaseMemory() {
  // If the cache was allocated, free it.
  if (PImpl) {
    delete &getCache(PImpl);
    PImpl = 0;
  }
}

Constant *LazyValueInfo::getConstant(Value *V, BasicBlock *BB) {
  LVILatticeVal Result = getCache(PImpl).getValueInBlock(V, BB);

  if (Result.isConstant())
    return Result.getConstant();
  return 0;
}

/// getConstantOnEdge - Determine whether the specified value is known to be a
/// constant on the specified edge.  Return null if not.
Constant *LazyValueInfo::getConstantOnEdge(Value *V, BasicBlock *FromBB,
                                           BasicBlock *ToBB) {
  LVILatticeVal Result = getCache(PImpl).getValueOnEdge(V, FromBB, ToBB);

  if (Result.isConstant())
    return Result.getConstant();
  return 0;
}

/// getPredicateOnEdge - Determine whether the specified value comparison
/// with a constant is known to be true or false on the specified CFG edge.
/// Pred is a CmpInst predicate.
LazyValueInfo::Tristate
LazyValueInfo::getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
                                  BasicBlock *FromBB, BasicBlock *ToBB) {
  LVILatticeVal Result = getCache(PImpl).getValueOnEdge(V, FromBB, ToBB);

  // If we know the value is a constant, evaluate the conditional.
  Constant *Res = 0;
  if (Result.isConstant()) {
    Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, TD);
    if (ConstantInt *ResCI = dyn_cast_or_null<ConstantInt>(Res))
      return ResCI->isZero() ? False : True;
    return Unknown;
  }

  if (Result.isNotConstant()) {
    // If this is an equality comparison, we can try to fold it knowing that
    // "V != C1".
    if (Pred == ICmpInst::ICMP_EQ) {
      // !C1 == C -> false iff C1 == C.
      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
                                            Result.getNotConstant(), C, TD);
      if (Res->isNullValue())
        return False;
    } else if (Pred == ICmpInst::ICMP_NE) {
      // !C1 != C -> true iff C1 == C.
      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_EQ,
                                            Result.getNotConstant(), C, TD);
      if (Res->isNullValue())
        return True;
    }
    return Unknown;
  }

  return Unknown;
}

<|endoftext|>


<commit_before>/*
 *  mcsignal_main.cpp
 *
 *  Created by Tobias Wood on 12/11/2012.
 *  Copyright (c) 2013 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include <string>
#include <iostream>
#include <getopt.h>
#include <exception>
#include <Eigen/Dense>
#include <Nifti/Nifti.h>
#include "QUIT/QUIT.h"
#include "Models.h"
#include "Sequence.h"

using namespace std;
using namespace Eigen;
using namespace QUIT;

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: mcsignal [options]\n\
\n\
Calculates multi-component DESPOT signals (mainly for testing purposes).\n\
The program will prompt for input (unless --no-prompt specified)\n\
\n\
All times (TR) are in SECONDS. All angles are in degrees.\n\
\n\
Options:\n\
	--help, -h        : Print this message.\n\
	--verbose, -v     : Print extra information.\n\
	--mask, -m file   : Only calculate inside the mask.\n\
	--out, -o path    : Add a prefix to the output filenames\n\
	--no-prompt, -n   : Don't print prompts for input.\n\
	--noise, -N val   : Add complex noise with std=val.\n\
	--1, --2, --3     : Use 1, 2 or 3 component sequences (default 3).\n\
	--sequences, -M s : Use simple sequences (default).\n\
	            f     : Use Finite Pulse Length correction.\n\
	--threads, -T N   : Use N threads (default=hardware limit)\n"
};

static shared_ptr<Model> model = make_shared<SCD>();
static bool verbose = false, prompt = true, finitesequences = false;
static string outPrefix = "";
static double sigma = 0.;
static struct option long_opts[] = {
	{"help", no_argument, 0, 'h'},
	{"verbose", no_argument, 0, 'v'},
	{"mask", required_argument, 0, 'm'},
	{"out", required_argument, 0, 'o'},
	{"no-prompt", no_argument, 0, 'n'},
	{"noise", required_argument, 0, 'N'},
	{"1", no_argument, 0, '1'},
	{"2", no_argument, 0, '2'},
	{"3", no_argument, 0, '3'},
	{"sequences", no_argument, 0, 'M'},
	{"threads", required_argument, 0, 'T'},
	{0, 0, 0, 0}
};
static const char *short_opts = "hvnN:m:o:123M:T:";
//******************************************************************************
#pragma mark Read in all required files and data from cin
//******************************************************************************
void parseInput(vector<shared_ptr<SequenceBase>> &cs, vector<string> &names);
void parseInput(vector<shared_ptr<SequenceBase>> &cs, vector<string> &names) {
	string type;
	if (prompt) cout << "Specify next signal type (SPGR/SSFP): " << flush;
	while (Read(cin, type) && (type != "END") && (type != "")) {
		if (type == "SPGR") {
			cs.push_back(make_shared<SPGRSimple>(prompt));
		} else if (type == "SPGRFinite") {
			cs.push_back(make_shared<SPGRFinite>(prompt));
		} else if (type == "SSFP") {
			cs.push_back(make_shared<SSFPSimple>(prompt));
		} else if (type == "SSFPFinite") {
			cs.push_back(make_shared<SSFPFinite>(prompt));
		} else if (type == "SSFPEllipse") {
			cs.push_back(make_shared<SSFPEllipse>(prompt));
		} else if (type == "IRSPGR") {
			cs.push_back(make_shared<IRSPGR>(prompt));
		} else if (type == "MPRAGE") {
			cs.push_back(make_shared<MPRAGE>(prompt));
		} else if (type == "SPINECHO") {
			cs.push_back(make_shared<MultiEcho>(prompt));
		} else {
			throw(std::runtime_error("Unknown signal type: " + type));
		}
		string filename;
		if (prompt) cout << "Enter output filename: " << flush;
		Read(cin, filename);
		names.push_back(filename);
		// Print message ready for next loop
		if (prompt) cout << "Specify next image type (SPGR/SSFP, END to finish input): " << flush;
	}
}
//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv)
{
	Eigen::initParallel();
	ThreadPool threads;

	try { // To fix uncaught exceptions on Mac

	Nifti::File maskFile, B1File;
	MultiArray<int8_t, 3> maskVol;
	MultiArray<float, 3> B1Vol;
	int indexptr = 0, c;
	while ((c = getopt_long(argc, argv, short_opts, long_opts, &indexptr)) != -1) {
		switch (c) {
			case 'v': verbose = true; break;
			case 'n': prompt = false; break;
			case 'N': sigma = atof(optarg); break;
			case 'm':
				cout << "Reading mask file " << optarg << endl;
				maskFile.open(optarg, Nifti::Mode::Read);
				maskVol.resize(maskFile.matrix());
				maskFile.readVolumes(maskVol.begin(), maskVol.end(), 0, 1);
				break;
			case 'o':
				outPrefix = optarg;
				cout << "Output prefix will be: " << outPrefix << endl;
				break;
			case '1': model = make_shared<SCD>(); break;
			case '2': model = make_shared<MCD2>(); break;
			case '3': model = make_shared<MCD3>(); break;
			case 'M':
				switch (*optarg) {
					case 's': finitesequences = false; if (prompt) cout << "Simple sequences selected." << endl; break;
					case 'f': finitesequences = true; if (prompt) cout << "Finite pulse correction selected." << endl; break;
					default:
						cout << "Unknown sequences type " << *optarg << endl;
						return EXIT_FAILURE;
						break;
				}
				break;
			case 'T': threads.resize(atoi(optarg)); break;
			case 'h':
			case '?': // getopt will print an error message
			default:
				cout << usage << endl;
				return EXIT_FAILURE;
		}
	}
	if ((argc - optind) != 0) {
		cerr << usage << endl << "Incorrect number of arguments." << endl;
		return EXIT_FAILURE;
	}
	if (verbose) cout << version << endl << credit_me << endl;
	if (verbose) cout << "Using " << model->Name() << " model." << endl;
	/***************************************************************************
	 * Read in parameter files
	 **************************************************************************/
	MultiArray<float, 4> paramsVols;
	Nifti::Header templateHdr;
	if (prompt) cout << "Loading parameters." << endl;
	for (size_t i = 0; i < model->nParameters(); i++) {
		if (prompt) cout << "Enter path to " << model->Names()[i] << " file: " << flush;
		string filename;
		getline(cin, filename);
		if (verbose) cout << "Opening " << filename << endl;
		Nifti::File input(filename);

		if (i == 0) {
			templateHdr = input.header();
			paramsVols = MultiArray<float, 4>(input.matrix(), model->nParameters());
		} else {
			if (!input.header().matchesSpace(templateHdr)) {
				cout << "Mismatched input volumes" << endl;
				return EXIT_FAILURE;
			}
		}
		auto inVol = paramsVols.slice<3>({0,0,0,i},{-1,-1,-1,0});
		if (verbose) cout << "Reading data." << endl;
		input.readVolumes(inVol.begin(), inVol.end(), 0, 1);
	}
	const auto d = paramsVols.dims();

	/***************************************************************************
	 * Set up sequences
	 **************************************************************************/
	vector<shared_ptr<SequenceBase>> sequences;
	vector<string> filenames;
	parseInput(sequences, filenames);
	if (verbose) {
		for (auto& s : sequences) {
			cout << *s << endl;
		}
	}

	vector<MultiArray<complex<float>, 4>> signalVols(sequences.size()); //d.head(3), sequences.combinedSize());
	for (size_t s = 0; s < sequences.size(); s++) {
		signalVols[s] = MultiArray<complex<float>, 4>(d.head(3), sequences.at(s)->size());
	}
	if (verbose) cout << "Calculating..." << endl;
	function<void (const size_t&)> calcVox = [&] (const size_t &k) {
		for (size_t j = 0; j < d[1]; j++) {
			for (size_t i = 0; i < d[0]; i++) {
				if (!maskFile || (maskVol[{i,j,k}])) {
					ArrayXd params = paramsVols.slice<1>({i,j,k,0},{0,0,0,-1}).asArray().cast<double>();
					for (size_t s = 0; s < sequences.size(); s++) {
						const size_t sigsize = sequences.at(s)->size();
						ArrayXcd signal = sequences.at(s)->signal(model, params);
						ArrayXcd noise(sigsize);
						mt19937_64 twister(RandomSeed());
						normal_distribution<double> gaussian(0., sigma / sqrt(2));
						for (ArrayXcd::Index i = 0; i < sigsize; i++) {
							noise.real()(i) = gaussian(twister);
							noise.imag()(i) = gaussian(twister);
						}
						signalVols[s].slice<1>({i,j,k,0},{0,0,0,-1}).asArray() = (signal + noise).cast<complex<float>>();
					}
				}
			}
		}
	};
	threads.for_loop(calcVox, d[2]);

	if (verbose) cout << "Finished calculating." << endl;
	if (verbose) cout << "Saving data." << endl;
	templateHdr.setDatatype(Nifti::DataType::COMPLEX64);
	size_t startVol = 0;
	for (size_t i = 0; i < sequences.size(); i++) {
		size_t thisSize = sequences.at(i)->size();
		templateHdr.setDim(4, thisSize);
		Nifti::File saveFile(templateHdr, outPrefix + filenames[i]);
		auto thisSignal = signalVols[i].slice<4>({0,0,0,startVol},{-1,-1,-1,thisSize});
		saveFile.writeVolumes(thisSignal.begin(), thisSignal.end());
		saveFile.close();
	}
	templateHdr.setDim(4, model->nParameters());
	Nifti::File checkParams(templateHdr, outPrefix + "_checkP.nii");
	checkParams.writeVolumes(paramsVols.begin(), paramsVols.end());
	checkParams.close();
	} catch (exception &e) {
		cerr << e.what() << endl;
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

<commit_msg>Removed the saved parameter check file.<commit_after>/*
 *  mcsignal_main.cpp
 *
 *  Created by Tobias Wood on 12/11/2012.
 *  Copyright (c) 2013 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include <string>
#include <iostream>
#include <getopt.h>
#include <exception>
#include <Eigen/Dense>
#include <Nifti/Nifti.h>
#include "QUIT/QUIT.h"
#include "Models.h"
#include "Sequence.h"

using namespace std;
using namespace Eigen;
using namespace QUIT;

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: mcsignal [options]\n\
\n\
Calculates multi-component DESPOT signals (mainly for testing purposes).\n\
The program will prompt for input (unless --no-prompt specified)\n\
\n\
All times (TR) are in SECONDS. All angles are in degrees.\n\
\n\
Options:\n\
	--help, -h        : Print this message.\n\
	--verbose, -v     : Print extra information.\n\
	--mask, -m file   : Only calculate inside the mask.\n\
	--out, -o path    : Add a prefix to the output filenames\n\
	--no-prompt, -n   : Don't print prompts for input.\n\
	--noise, -N val   : Add complex noise with std=val.\n\
	--1, --2, --3     : Use 1, 2 or 3 component sequences (default 3).\n\
	--sequences, -M s : Use simple sequences (default).\n\
	            f     : Use Finite Pulse Length correction.\n\
	--threads, -T N   : Use N threads (default=hardware limit)\n"
};

static shared_ptr<Model> model = make_shared<SCD>();
static bool verbose = false, prompt = true, finitesequences = false;
static string outPrefix = "";
static double sigma = 0.;
static struct option long_opts[] = {
	{"help", no_argument, 0, 'h'},
	{"verbose", no_argument, 0, 'v'},
	{"mask", required_argument, 0, 'm'},
	{"out", required_argument, 0, 'o'},
	{"no-prompt", no_argument, 0, 'n'},
	{"noise", required_argument, 0, 'N'},
	{"1", no_argument, 0, '1'},
	{"2", no_argument, 0, '2'},
	{"3", no_argument, 0, '3'},
	{"sequences", no_argument, 0, 'M'},
	{"threads", required_argument, 0, 'T'},
	{0, 0, 0, 0}
};
static const char *short_opts = "hvnN:m:o:123M:T:";
//******************************************************************************
#pragma mark Read in all required files and data from cin
//******************************************************************************
void parseInput(vector<shared_ptr<SequenceBase>> &cs, vector<string> &names);
void parseInput(vector<shared_ptr<SequenceBase>> &cs, vector<string> &names) {
	string type;
	if (prompt) cout << "Specify next signal type (SPGR/SSFP): " << flush;
	while (Read(cin, type) && (type != "END") && (type != "")) {
		if (type == "SPGR") {
			cs.push_back(make_shared<SPGRSimple>(prompt));
		} else if (type == "SPGRFinite") {
			cs.push_back(make_shared<SPGRFinite>(prompt));
		} else if (type == "SSFP") {
			cs.push_back(make_shared<SSFPSimple>(prompt));
		} else if (type == "SSFPFinite") {
			cs.push_back(make_shared<SSFPFinite>(prompt));
		} else if (type == "SSFPEllipse") {
			cs.push_back(make_shared<SSFPEllipse>(prompt));
		} else if (type == "IRSPGR") {
			cs.push_back(make_shared<IRSPGR>(prompt));
		} else if (type == "MPRAGE") {
			cs.push_back(make_shared<MPRAGE>(prompt));
		} else if (type == "SPINECHO") {
			cs.push_back(make_shared<MultiEcho>(prompt));
		} else {
			throw(std::runtime_error("Unknown signal type: " + type));
		}
		string filename;
		if (prompt) cout << "Enter output filename: " << flush;
		Read(cin, filename);
		names.push_back(filename);
		// Print message ready for next loop
		if (prompt) cout << "Specify next image type (SPGR/SSFP, END to finish input): " << flush;
	}
}
//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv)
{
	Eigen::initParallel();
	ThreadPool threads;

	try { // To fix uncaught exceptions on Mac

	Nifti::File maskFile, B1File;
	MultiArray<int8_t, 3> maskVol;
	MultiArray<float, 3> B1Vol;
	int indexptr = 0, c;
	while ((c = getopt_long(argc, argv, short_opts, long_opts, &indexptr)) != -1) {
		switch (c) {
			case 'v': verbose = true; break;
			case 'n': prompt = false; break;
			case 'N': sigma = atof(optarg); break;
			case 'm':
				cout << "Reading mask file " << optarg << endl;
				maskFile.open(optarg, Nifti::Mode::Read);
				maskVol.resize(maskFile.matrix());
				maskFile.readVolumes(maskVol.begin(), maskVol.end(), 0, 1);
				break;
			case 'o':
				outPrefix = optarg;
				cout << "Output prefix will be: " << outPrefix << endl;
				break;
			case '1': model = make_shared<SCD>(); break;
			case '2': model = make_shared<MCD2>(); break;
			case '3': model = make_shared<MCD3>(); break;
			case 'M':
				switch (*optarg) {
					case 's': finitesequences = false; if (prompt) cout << "Simple sequences selected." << endl; break;
					case 'f': finitesequences = true; if (prompt) cout << "Finite pulse correction selected." << endl; break;
					default:
						cout << "Unknown sequences type " << *optarg << endl;
						return EXIT_FAILURE;
						break;
				}
				break;
			case 'T': threads.resize(atoi(optarg)); break;
			case 'h':
			case '?': // getopt will print an error message
			default:
				cout << usage << endl;
				return EXIT_FAILURE;
		}
	}
	if ((argc - optind) != 0) {
		cerr << usage << endl << "Incorrect number of arguments." << endl;
		return EXIT_FAILURE;
	}
	if (verbose) cout << version << endl << credit_me << endl;
	if (verbose) cout << "Using " << model->Name() << " model." << endl;
	/***************************************************************************
	 * Read in parameter files
	 **************************************************************************/
	MultiArray<float, 4> paramsVols;
	Nifti::Header templateHdr;
	if (prompt) cout << "Loading parameters." << endl;
	for (size_t i = 0; i < model->nParameters(); i++) {
		if (prompt) cout << "Enter path to " << model->Names()[i] << " file: " << flush;
		string filename;
		getline(cin, filename);
		if (verbose) cout << "Opening " << filename << endl;
		Nifti::File input(filename);

		if (i == 0) {
			templateHdr = input.header();
			paramsVols = MultiArray<float, 4>(input.matrix(), model->nParameters());
		} else {
			if (!input.header().matchesSpace(templateHdr)) {
				cout << "Mismatched input volumes" << endl;
				return EXIT_FAILURE;
			}
		}
		auto inVol = paramsVols.slice<3>({0,0,0,i},{-1,-1,-1,0});
		if (verbose) cout << "Reading data." << endl;
		input.readVolumes(inVol.begin(), inVol.end(), 0, 1);
	}
	const auto d = paramsVols.dims();

	/***************************************************************************
	 * Set up sequences
	 **************************************************************************/
	vector<shared_ptr<SequenceBase>> sequences;
	vector<string> filenames;
	parseInput(sequences, filenames);
	if (verbose) {
		for (auto& s : sequences) {
			cout << *s << endl;
		}
	}

	vector<MultiArray<complex<float>, 4>> signalVols(sequences.size()); //d.head(3), sequences.combinedSize());
	for (size_t s = 0; s < sequences.size(); s++) {
		signalVols[s] = MultiArray<complex<float>, 4>(d.head(3), sequences.at(s)->size());
	}
	if (verbose) cout << "Calculating..." << endl;
	function<void (const size_t&)> calcVox = [&] (const size_t &k) {
		for (size_t j = 0; j < d[1]; j++) {
			for (size_t i = 0; i < d[0]; i++) {
				if (!maskFile || (maskVol[{i,j,k}])) {
					ArrayXd params = paramsVols.slice<1>({i,j,k,0},{0,0,0,-1}).asArray().cast<double>();
					for (size_t s = 0; s < sequences.size(); s++) {
						const size_t sigsize = sequences.at(s)->size();
						ArrayXcd signal = sequences.at(s)->signal(model, params);
						ArrayXcd noise(sigsize);
						mt19937_64 twister(RandomSeed());
						normal_distribution<double> gaussian(0., sigma / sqrt(2));
						for (ArrayXcd::Index i = 0; i < sigsize; i++) {
							noise.real()(i) = gaussian(twister);
							noise.imag()(i) = gaussian(twister);
						}
						signalVols[s].slice<1>({i,j,k,0},{0,0,0,-1}).asArray() = (signal + noise).cast<complex<float>>();
					}
				}
			}
		}
	};
	threads.for_loop(calcVox, d[2]);

	if (verbose) cout << "Finished calculating." << endl;
	if (verbose) cout << "Saving data." << endl;
	templateHdr.setDatatype(Nifti::DataType::COMPLEX64);
	size_t startVol = 0;
	for (size_t i = 0; i < sequences.size(); i++) {
		size_t thisSize = sequences.at(i)->size();
		templateHdr.setDim(4, thisSize);
		Nifti::File saveFile(templateHdr, outPrefix + filenames[i]);
		auto thisSignal = signalVols[i].slice<4>({0,0,0,startVol},{-1,-1,-1,thisSize});
		saveFile.writeVolumes(thisSignal.begin(), thisSignal.end());
		saveFile.close();
	}
	} catch (exception &e) {
		cerr << e.what() << endl;
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>#include "ActionFactory.h"

#include "actasp/Action.h"
#include <boost/config/no_tr1/complex.hpp>

using namespace std;
using namespace actasp;

namespace bwi_krexec {

bool ActionFactory::simulation(false);

ActionFactory::ActionFactory(Action* act) {

	//TODO warn if action already there
	bothActions().insert( make_pair(act->getName(),act));

}

ActionFactory::ActionFactory(actasp::Action *act, bool simulation) {

	if(simulation)
		simulatedActions().insert( make_pair(act->getName(),act));
	else
		realActions().insert( make_pair(act->getName(),act));
}

Action* ActionFactory::byName(const std::string& name) throw (std::runtime_error) {

	map<string, Action*>::const_iterator actIt = bothActions().find(name);

	if(actIt == actions().end()) {

		ActionMap &inUse = (simulation)? simulatedActions() : realActions();

		actIt = inUse.find(name);
		if(actIt == inUse.end())
			throw runtime_error("No action with name " + name);
	}

	return actIt->second->clone();
}

ActionFactory::ActionMap ActionFactory::actions() {
	ActionFactory::ActionMap actions(bothActions().begin(),bothActions().end());
	if(simulation)
		actions.insert(simulatedActions().begin(),simulatedActions().end());
	else
		actions.insert(realActions().begin(),realActions().end());

	return actions;
}

ActionFactory::ActionMap &ActionFactory::realActions() {
	static ActionFactory::ActionMap realAct;
	return realAct;
}

ActionFactory::ActionMap &ActionFactory::simulatedActions() {
	static ActionFactory::ActionMap simulAct;
	return simulAct;
}

ActionFactory::ActionMap &ActionFactory::bothActions() {
	static ActionFactory::ActionMap bothAct;
	return bothAct;
}

void ActionFactory::setSimulation(bool value) {
	simulation = value;
}

}<commit_msg>giving higher priority in the action factory to actions that are either for the real robot or simulation, but not both<commit_after>#include "ActionFactory.h"

#include "actasp/Action.h"
#include <boost/config/no_tr1/complex.hpp>

using namespace std;
using namespace actasp;

namespace bwi_krexec {

bool ActionFactory::simulation(false);

ActionFactory::ActionFactory(Action* act) {

	//TODO warn if action already there
	bothActions().insert( make_pair(act->getName(),act));

}

ActionFactory::ActionFactory(actasp::Action *act, bool simulation) {

	if(simulation)
		simulatedActions().insert( make_pair(act->getName(),act));
	else
		realActions().insert( make_pair(act->getName(),act));
}

Action* ActionFactory::byName(const std::string& name) throw (std::runtime_error) {

	map<string, Action*>::const_iterator actIt = bothActions().find(name);

	if(actIt == actions().end()) {

		ActionMap &inUse = (simulation)? simulatedActions() : realActions();

		actIt = inUse.find(name);
		if(actIt == inUse.end())
			throw runtime_error("No action with name " + name);
	}

	return actIt->second->clone();
}

ActionFactory::ActionMap ActionFactory::actions() {
	ActionFactory::ActionMap actions;
	if(simulation)
		actions.insert(simulatedActions().begin(),simulatedActions().end());
	else
		actions.insert(realActions().begin(),realActions().end());

  actions.insert(bothActions().begin(),bothActions().end());

	return actions;
}

ActionFactory::ActionMap &ActionFactory::realActions() {
	static ActionFactory::ActionMap realAct;
	return realAct;
}

ActionFactory::ActionMap &ActionFactory::simulatedActions() {
	static ActionFactory::ActionMap simulAct;
	return simulAct;
}

ActionFactory::ActionMap &ActionFactory::bothActions() {
	static ActionFactory::ActionMap bothAct;
	return bothAct;
}

void ActionFactory::setSimulation(bool value) {
	simulation = value;
}

}<|endoftext|>


<commit_before>#include "interfaz.h"

char Interfaz::vMenuPrincipal()
{
	char ans;
	cout << endl << endl;
	cout << "**************MENU PRINCIPAL**************" << endl;
	cout << "(1)--Informacion acerca de la Universidad" << endl;
	cout << "(2)--Lista de Escuelas" << endl;
	cout << "(3)--Ajustes" << endl;
	cout << "(4)--Salir" << endl;
	cout << "******************************************" << endl;

	ans = _getch();

	while (ans != '1' && ans != '2' && ans != '3' && ans != '4')
	{
		cout << "Opcion Incorrecta. Try again " << endl;
		ans = _getch();
	}

	system("cls");
	return ans;
}

char Interfaz::vMenuAjustes(Universidad* U)
{
	char ans;

	if (U->getNombre() == "Undefined")
	{
		cout << "-(1)-Ingresar nombre de la Universidad" << endl;
		cout << "-(2)-Cambiar Numero de Telefono de la Universidad" << endl;
		cout << "-(3)-Cambiar Direccion de la Universidad" << endl;
		cout << "-(4)-Salir" << endl;

		ans = _getch();

		while (ans != '1' && ans != '2' && ans != '3' && ans != '4')
		{
			cout << "Opcion Incorrecta. Try again " << endl;
			ans = _getch();
		}
	}
	else
	{
		cout << "-(1)-Cambiar Numero de Telefono de la Universidad" << endl;
		cout << "-(2)-Cambiar Direccion de la Universidad" << endl;
		cout << "-(3)-Salir" << endl;

		ans = _getch();

		while (ans != '1' && ans != '2' && ans != '3')
		{
			cout << "Opcion Incorrecta. Try again " << endl;
			ans = _getch();
		}
	}

	system("cls");
	return ans;
}

void Interfaz::vIngresarNumero(Universidad* U)
{
	char ans;

	do
	{
		Sleep(500);
		cout << "Ingrese el numero de telefono -> "; string numero;
		std::cin >> numero; cin.ignore();

		while (chequeaNumero(numero) == false) //No le permite al usuario ingresar un algo que no sean numeros
		{
			cout << "Numero Invalido. Intente de nuevo";
			Sleep(800);
			system("cls");
			cout << string("Ingrese el numero de telefono -> "); cin.clear();
			std::cin >> numero; cin.ignore();
		}

		cout << endl << endl;
		cout << "Numero : " << "\"" << numero << "\" "; cout << "| es esta informacion correcta?";

		ans = vInfoConfirmacion();

		if (ans == 'S')
		{
			U->setTelefono(numero);
			msjPerfecto();
		}

	} while (ans == 'N');
}

void Interfaz::vIngresarDireccion(Universidad* U)
{
	char ans;

	do
	{
		Sleep(500);
		cout << "Ingrese la direccion -> "; string direccion; getline(std::cin, direccion); cout << endl << endl;
		cout << "Direccion : " << "\"" << direccion << "\" "; cout << "| es esta informacion correcta?";

		ans = vInfoConfirmacion();

		if (ans == 'S')
		{
			U->setDireccion(direccion);
			msjPerfecto();
		}

	} while (ans == 'N');
}

void Interfaz::vIngresarNombre(Universidad* U)
{
	char ans;
	do //Pide los datos al usuario y le da la opcion de cambiarlos las veces que quiera mientras no confirme su opcion
	{
		Sleep(500);
		cout << string("Ingrese el nombre de la Universidad -> "); string nombre; std::getline(std::cin, nombre); cout << endl << endl;

		cout << "Universidad : " << "\"" << nombre << "\" "; cout << "| es esta informacion correcta? (El nombre no se puede cambiar una vez confirmado)";

		ans = vInfoConfirmacion();

		while (nombre == "Undefined" || nombre == " ")
		{
			cout << "Nombre Invalido. Intente de nuevo -> ";
			Sleep(800);
			system("cls");
			cout << "Ingrese el nombre de la Universidad  -> "; string nombre; std::getline(std::cin, nombre); cout << endl << endl;
		}

		if (ans == 'S') //Solo ingresa al nombre si el usuario confirma
		{
			U->setNombre(nombre);
			msjPerfecto();
		}

	} while (ans == 'N');
}

char Interfaz::vInfoConfirmacion()
{
	char ans;

	cout << string("| SI (S) NO (N)") << endl;

	ans = toupper(_getch());

	while (ans != 'S' && ans != 'N') //Impide ingresar un valor diferente a S o N
	{
		ans = toupper(_getch());
	}

	return ans;
}

bool Interfaz::chequeaNumero(string num)
{
	bool esNumero;

	for (size_t x = 0; x < num.length(); x++)
	{
		if (isdigit(num[x]))
			esNumero = true;
		else
		{
			esNumero = false;
			return esNumero;
		}
	}
	return esNumero;
}

string Interfaz::convierteaMayusculas(string minuscula)
{
	string mayuscula;
	for (size_t i = 0; i < minuscula.length(); i++)
	{
		mayuscula += toupper(minuscula[i]);
	}

	return mayuscula;
}

void Interfaz::msjPerfecto()
{
	cout << endl << string("Perfecto!");
	Sleep(1500);
	system("cls");
}

void Interfaz::msjNoDatosIngresadosUni()
{
	cout << "Ups... parece que no se han ingresado todos los datos de la Universidad. Ve a Ajustes para agregarlos.";
	Sleep(2000);
	system("cls");
}

void Interfaz::vtoString(Universidad* U) //Modificar para que sirva de informacion actual del sistema de matricula
{
	Sleep(500);
	system("cls");
	cout << U->toString() << endl;
	system("pause");
	system("cls");
}
<commit_msg>eliminio unos endl innecesarios<commit_after>#include "interfaz.h"

char Interfaz::vMenuPrincipal()
{
	char ans;
	cout << "**************MENU PRINCIPAL**************" << endl;
	cout << "(1)--Informacion acerca de la Universidad" << endl;
	cout << "(2)--Lista de Escuelas" << endl;
	cout << "(3)--Ajustes" << endl;
	cout << "(4)--Salir" << endl;
	cout << "******************************************" << endl;

	ans = _getch();

	while (ans != '1' && ans != '2' && ans != '3' && ans != '4')
	{
		cout << "Opcion Incorrecta. Try again " << endl;
		ans = _getch();
	}

	system("cls");
	return ans;
}

char Interfaz::vMenuAjustes(Universidad* U)
{
	char ans;

	if (U->getNombre() == "Undefined")
	{
		cout << "-(1)-Ingresar nombre de la Universidad" << endl;
		cout << "-(2)-Cambiar Numero de Telefono de la Universidad" << endl;
		cout << "-(3)-Cambiar Direccion de la Universidad" << endl;
		cout << "-(4)-Salir" << endl;

		ans = _getch();

		while (ans != '1' && ans != '2' && ans != '3' && ans != '4')
		{
			cout << "Opcion Incorrecta. Try again " << endl;
			ans = _getch();
		}
	}
	else
	{
		cout << "-(1)-Cambiar Numero de Telefono de la Universidad" << endl;
		cout << "-(2)-Cambiar Direccion de la Universidad" << endl;
		cout << "-(3)-Salir" << endl;

		ans = _getch();

		while (ans != '1' && ans != '2' && ans != '3')
		{
			cout << "Opcion Incorrecta. Try again " << endl;
			ans = _getch();
		}
	}

	system("cls");
	return ans;
}

void Interfaz::vIngresarNumero(Universidad* U)
{
	char ans;

	do
	{
		Sleep(500);
		cout << "Ingrese el numero de telefono -> "; string numero;
		std::cin >> numero; cin.ignore();

		while (chequeaNumero(numero) == false) //No le permite al usuario ingresar un algo que no sean numeros
		{
			cout << "Numero Invalido. Intente de nuevo";
			Sleep(800);
			system("cls");
			cout << string("Ingrese el numero de telefono -> "); cin.clear();
			std::cin >> numero; cin.ignore();
		}

		cout << endl << endl;
		cout << "Numero : " << "\"" << numero << "\" "; cout << "| es esta informacion correcta?";

		ans = vInfoConfirmacion();

		if (ans == 'S')
		{
			U->setTelefono(numero);
			msjPerfecto();
		}

	} while (ans == 'N');
}

void Interfaz::vIngresarDireccion(Universidad* U)
{
	char ans;

	do
	{
		Sleep(500);
		cout << "Ingrese la direccion -> "; string direccion; getline(std::cin, direccion); cout << endl << endl;
		cout << "Direccion : " << "\"" << direccion << "\" "; cout << "| es esta informacion correcta?";

		ans = vInfoConfirmacion();

		if (ans == 'S')
		{
			U->setDireccion(direccion);
			msjPerfecto();
		}

	} while (ans == 'N');
}

void Interfaz::vIngresarNombre(Universidad* U)
{
	char ans;
	do //Pide los datos al usuario y le da la opcion de cambiarlos las veces que quiera mientras no confirme su opcion
	{
		Sleep(500);
		cout << string("Ingrese el nombre de la Universidad -> "); string nombre; std::getline(std::cin, nombre); cout << endl << endl;

		cout << "Universidad : " << "\"" << nombre << "\" "; cout << "| es esta informacion correcta? (El nombre no se puede cambiar una vez confirmado)";

		ans = vInfoConfirmacion();

		while (nombre == "Undefined" || nombre == " ")
		{
			cout << "Nombre Invalido. Intente de nuevo -> ";
			Sleep(800);
			system("cls");
			cout << "Ingrese el nombre de la Universidad  -> "; string nombre; std::getline(std::cin, nombre); cout << endl << endl;
		}

		if (ans == 'S') //Solo ingresa al nombre si el usuario confirma
		{
			U->setNombre(nombre);
			msjPerfecto();
		}

	} while (ans == 'N');
}

char Interfaz::vInfoConfirmacion()
{
	char ans;

	cout << string("| SI (S) NO (N)") << endl;

	ans = toupper(_getch());

	while (ans != 'S' && ans != 'N') //Impide ingresar un valor diferente a S o N
	{
		ans = toupper(_getch());
	}

	return ans;
}

bool Interfaz::chequeaNumero(string num)
{
	bool esNumero;

	for (size_t x = 0; x < num.length(); x++)
	{
		if (isdigit(num[x]))
			esNumero = true;
		else
		{
			esNumero = false;
			return esNumero;
		}
	}
	return esNumero;
}

string Interfaz::convierteaMayusculas(string minuscula)
{
	string mayuscula;
	for (size_t i = 0; i < minuscula.length(); i++)
	{
		mayuscula += toupper(minuscula[i]);
	}

	return mayuscula;
}

void Interfaz::msjPerfecto()
{
	cout << endl << string("Perfecto!");
	Sleep(1500);
	system("cls");
}

void Interfaz::msjNoDatosIngresadosUni()
{
	cout << "Ups... parece que no se han ingresado todos los datos de la Universidad. Ve a Ajustes para agregarlos.";
	Sleep(2000);
	system("cls");
}

void Interfaz::vtoString(Universidad* U) //Modificar para que sirva de informacion actual del sistema de matricula
{
	Sleep(500);
	system("cls");
	cout << U->toString() << endl;
	system("pause");
	system("cls");
}
<|endoftext|>


<commit_before>// Copyright (c) 2011-2012, Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include <cstring>
#include <ctime>
#include <exception>
#include <iterator>
#include <list>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <amx/amx.h>
#include <amx/amxaux.h>
#ifdef _WIN32
	#include <windows.h>
	#include <sys/types.h>
	#include <sys/stat.h>
	#if !defined stat
		#define stat _stat
	#endif
#else
	#include <dirent.h>
	#include <fnmatch.h>
	#include <sys/stat.h>
#endif
#include "amx_path.h"

static time_t GetMtime(const std::string filename) {
	struct stat attrib;
	stat(filename.c_str(), &attrib);
	return attrib.st_mtime;
}

class AmxFile {
public:
	static void FreeAmx(AMX *amx);

	explicit AmxFile(const std::string &name);

	bool IsLoaded() const {
		return amxPtr_.get() != 0;
	}

	const AMX *GetAmx() const {
		return amxPtr_.get();
	}

	const std::string &GetName() const {
		return name_;
	}

	std::time_t GetLastWriteTime() const {
		return last_write_;
	}

private:
	std::shared_ptr<AMX> amxPtr_;
	std::string name_;
	std::time_t last_write_;
};

AmxFile::AmxFile(const std::string &name)
	: name_(name)
	, last_write_(GetMtime(name))
	, amxPtr_(new AMX, FreeAmx)
{
	if (aux_LoadProgram(amxPtr_.get(), const_cast<char*>(name.c_str()), 0) != AMX_ERR_NONE) {
		amxPtr_.reset();
	}
}

void AmxFile::FreeAmx(AMX *amx) {
	aux_FreeProgram(amx);
	delete amx;
}

static std::unordered_map<std::string, AmxFile> scripts;
static std::unordered_map<AMX*, std::string> cachedNames;

template<typename OutputIterator>
static void GetFilesInDirectory(const std::string &dir,
								const std::string &pattern,
								OutputIterator result) {
#if defined _WIN32
	WIN32_FIND_DATA findFileData;
	HANDLE hFindFile = FindFirstFile((dir + "\\" + pattern).c_str(), &findFileData);
	if (hFindFile != INVALID_HANDLE_VALUE) {
		do {
			if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
				*result++ = dir + "\\" + findFileData.cFileName;
			}
		} while (FindNextFile(hFindFile, &findFileData) != 0);
		FindClose(hFindFile);
	}
#else
	DIR *dp;
	if ((dp = opendir(dir.c_str())) != 0) {
		struct dirent *dirp;
		while ((dirp = readdir(dp)) != 0) {
			if (!fnmatch(pattern.c_str(), dirp->d_name,
							FNM_CASEFOLD | FNM_NOESCAPE | FNM_PERIOD)) {
				*result++ = dir + "/" + dirp->d_name;
			}
		}
		closedir(dp);
	}
#endif
}

std::string GetAmxPath(AMX_HEADER *amxhdr) {
	std::string result;

	std::list<std::string> files;
	GetFilesInDirectory("gamemodes", "*.amx", std::back_inserter(files));
	GetFilesInDirectory("filterscripts", "*.amx", std::back_inserter(files));

	for (auto &file : files) {
		auto script_it = scripts.find(file);
		if (script_it == scripts.end() ||
				script_it->second.GetLastWriteTime() < GetMtime(file)) {
			if (script_it != scripts.end()) {
				scripts.erase(script_it);
			}
			AmxFile script_it(file);
			if (script_it.IsLoaded()) {
				scripts.insert(std::make_pair(file, script_it));
			}
		}
	}

	for (auto &string_script : scripts) {
		void *amxhdr2 = string_script.second.GetAmx()->base;
		if (std::memcmp(amxhdr, amxhdr2, sizeof(AMX_HEADER)) == 0) {
			result = string_script.first;
			break;
		}
	}

	return result;
}

std::string GetAmxPath(AMX *amx) {
	std::string result;

	auto it = cachedNames.find(amx);
	if (it != cachedNames.end()) {
		result = it->second;
	} else {
		result = GetAmxPath(reinterpret_cast<AMX_HEADER*>(amx->base));
		if (!result.empty()) {
			cachedNames.insert(std::make_pair(amx, result));
		}
	}

	return result;
}
<commit_msg>Fix crash when AmxFile fails to load the .amx file<commit_after>// Copyright (c) 2011-2012, Zeex
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

#include <cstring>
#include <ctime>
#include <exception>
#include <iterator>
#include <list>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <amx/amx.h>
#include <amx/amxaux.h>
#ifdef _WIN32
	#include <windows.h>
	#include <sys/types.h>
	#include <sys/stat.h>
	#if !defined stat
		#define stat _stat
	#endif
#else
	#include <dirent.h>
	#include <fnmatch.h>
	#include <sys/stat.h>
#endif
#include "amx_path.h"

static time_t GetMtime(const std::string filename) {
	struct stat attrib;
	stat(filename.c_str(), &attrib);
	return attrib.st_mtime;
}

class AmxFile {
public:
	static void FreeAmx(AMX *amx);

	explicit AmxFile(const std::string &name);

	bool IsLoaded() const {
		return amxPtr_.get() != 0;
	}

	const AMX *GetAmx() const {
		return amxPtr_.get();
	}

	const std::string &GetName() const {
		return name_;
	}

	std::time_t GetLastWriteTime() const {
		return last_write_;
	}

private:
	std::shared_ptr<AMX> amxPtr_;
	std::string name_;
	std::time_t last_write_;
};

AmxFile::AmxFile(const std::string &name)
	: name_(name)
	, last_write_(GetMtime(name))
{
	if (AMX *amx = new AMX) {
		std::memset(amx, 0, sizeof(AMX));
		if (aux_LoadProgram(amx, const_cast<char*>(name.c_str()), 0) == AMX_ERR_NONE) {
			amxPtr_.reset(amx, FreeAmx);
		} else {
			delete amx;
		}
	}
}

void AmxFile::FreeAmx(AMX *amx) {
	if (amx != 0) {
		aux_FreeProgram(amx);
		delete amx;
	}
}

static std::unordered_map<std::string, AmxFile> scripts;
static std::unordered_map<AMX*, std::string> cachedNames;

template<typename OutputIterator>
static void GetFilesInDirectory(const std::string &dir,
								const std::string &pattern,
								OutputIterator result) {
#if defined _WIN32
	WIN32_FIND_DATA findFileData;
	HANDLE hFindFile = FindFirstFile((dir + "\\" + pattern).c_str(), &findFileData);
	if (hFindFile != INVALID_HANDLE_VALUE) {
		do {
			if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
				*result++ = dir + "\\" + findFileData.cFileName;
			}
		} while (FindNextFile(hFindFile, &findFileData) != 0);
		FindClose(hFindFile);
	}
#else
	DIR *dp;
	if ((dp = opendir(dir.c_str())) != 0) {
		struct dirent *dirp;
		while ((dirp = readdir(dp)) != 0) {
			if (!fnmatch(pattern.c_str(), dirp->d_name,
							FNM_CASEFOLD | FNM_NOESCAPE | FNM_PERIOD)) {
				*result++ = dir + "/" + dirp->d_name;
			}
		}
		closedir(dp);
	}
#endif
}

std::string GetAmxPath(AMX_HEADER *amxhdr) {
	std::string result;

	std::list<std::string> files;
	GetFilesInDirectory("gamemodes", "*.amx", std::back_inserter(files));
	GetFilesInDirectory("filterscripts", "*.amx", std::back_inserter(files));

	for (auto &file : files) {
		auto script_it = scripts.find(file);
		if (script_it == scripts.end() ||
				script_it->second.GetLastWriteTime() < GetMtime(file)) {
			if (script_it != scripts.end()) {
				scripts.erase(script_it);
			}
			AmxFile script_it(file);
			if (script_it.IsLoaded()) {
				scripts.insert(std::make_pair(file, script_it));
			}
		}
	}

	for (auto &string_script : scripts) {
		void *amxhdr2 = string_script.second.GetAmx()->base;
		if (std::memcmp(amxhdr, amxhdr2, sizeof(AMX_HEADER)) == 0) {
			result = string_script.first;
			break;
		}
	}

	return result;
}

std::string GetAmxPath(AMX *amx) {
	std::string result;

	auto it = cachedNames.find(amx);
	if (it != cachedNames.end()) {
		result = it->second;
	} else {
		result = GetAmxPath(reinterpret_cast<AMX_HEADER*>(amx->base));
		if (!result.empty()) {
			cachedNames.insert(std::make_pair(amx, result));
		}
	}

	return result;
}
<|endoftext|>