/* Program to read an aligment file in "Ronan's format" Sometimes there are two lines for each wafer, one for the r-phi side and one for the z side, the latter is currently ignored. The order of the numbers is: CDF_code = digicode barrel = 0-3 layer wedge side =0 for r-phi wafer = 0 or 1 for SVX, count in +CDFz for half=0, -CDFz for half=1 half = half ladder =0 for half barrels 0, 2, 4 counting from 0 in +CDFz v_x v_y v_z = vector for wafer position the z is the half-ladder z sh_x sh_y sh_z = short (r-phi) direction (alternates with +/- half) lo_x lo_y lo_z = long (z) direction (alternates with +/- half) n_x n_y n_z = normal to plane The SVX has entries for each wafer. The entry for the phi side is followed by an entry for the z side which is ignored. For the ISL there are only entries for wafer=0 which stands for the halfladder. The z in this case is the z of the central of the 3 wafers. usage: TranslateVectors ronan_format_file three files are written out: all of the alignment put into the wafer position: vecwaf.txt the alignment broken down into ladder position (bulk of alignment) and the rest in the wafer position: veclad.txt and finally the bows only in vecbow.txt (Tx and Ay from veclad.txt, but only for the wafers). */ #include #include #include #include #include #include "Alignment/AlDigiCode.hh" #include "Alignment/AlHolder.hh" #include "CLHEP/Geometry/Transform3D.h" #include "CLHEP/Vector/Rotation.h" #include "CLHEP/Vector/ThreeVector.h" class Geom { // position of wafer center wrt center of halfladder // for ISL this the position of the wafer on ends // SVX has gap corrections, ISL does not public: static double waferZ(int layer) { double waferZ[8] = {3.92, 3.7174,3.71718,3.72018,3.7173,3.71965, 6.9020,7.4772}; return waferZ[layer]; } }; class VectorEntry { public: VectorEntry():filled(false) {} void setCenter(double x, double y, double z) { center = Hep3Vector(x,y,z); } void setShort (double x, double y, double z) { shortv = Hep3Vector(x,y,z); } void setLong (double x, double y, double z) { longv = Hep3Vector(x,y,z); } void setNormal(double x, double y, double z) { normal = Hep3Vector(x,y,z); } void setInts (int CDF_codea, int barrela, int layera, int wedgea, int sidea, int wafera, int halfa) { CDF_code=CDF_codea; barrel=barrela; layer=layera; wedge=wedgea; side=sidea; wafer=wafera; half=halfa; } void setTransform(HepTransform3D t) { tr = t; } void setBarrel(int i) {barrel = i;} void setLayer (int i) {layer = i; } void setWedge (int i) {wedge = i; } void setSide (int i) {side = i; } void setWafer (int i) {wafer = i;} void setHalf (int i) {half = i; } void setFilled(bool tf) {filled = tf; } bool getFilled() { return filled; } Hep3Vector getCenter() {return center; } Hep3Vector getShort() {return shortv; } Hep3Vector getLong() {return longv; } Hep3Vector getNormal() {return normal; } int getBarrel() {return barrel;} int getLayer () {return layer; } int getWedge () {return wedge; } int getSide () {return side; } int getWafer () {return wafer;} int getHalf () {return half; } AlDigiCode getAlDigiCode() { AlDigiCode al; al.setResolution(AlDigiCode::WAFER); al.setPar(barrel,layer,wedge,half,wafer); return al; } HepTransform3D getTransform() { return tr;} bool readEntry(ifstream& is){ double v_x, v_y, v_z, sh_x, sh_y, sh_z, lo_x, lo_y, lo_z, n_x, n_y, n_z; is >> CDF_code; if(is.eof()) return false; is >> barrel >> layer >> wedge >> side >> wafer >> half; is >> v_x >> v_y >> v_z >> sh_x >> sh_y >> sh_z >> lo_x >> lo_y >> lo_z >> n_x >> n_y >> n_z; // temporary fix for vec_02.txt !!!!!!!! // switch half and side //if(layer>5) { // int itemp = side; // side = half; // half = itemp; //} // ignoring L00 for now !!!!!!!! if( (fabs(v_x)>0.0 || fabs(v_y)>0.0 ) && side==0 && layer!=0) { setCenter(v_x, v_y, v_z); setLong(lo_x, lo_y, lo_z); setShort(sh_x, sh_y, sh_z); setNormal(n_x, n_y, n_z); Hep3Vector pos(v_x, v_y, v_z); HepRotation r; Hep3Vector newX(n_x, n_y, n_z); Hep3Vector newY(sh_x, sh_y, sh_z); Hep3Vector newZ(lo_x, lo_y, lo_z); /* cout << " reading " << barrel << " " << layer << " " << wedge << " " << side << " " << wafer << " " << half << endl; cout << "x" <=1 && layer<=5) { if(wafer==0) wp = -wp; } else if(layer>=6) { // currently, for ISL, wafer=0 stands in for halfladder!! //if(wafer==0) { // wp = -wp; //} else if(wafer==1) { wp = 0.0; // center of three wafers //} } HepTranslateZ3D waferShift(wp); tr = HepTransform3D(r, pos)*waferShift; filled=true; } // end if entry is non-zero // if(layer>=1 && layer<=5) { // now read the z side and ignore it //is >> CDF_code >> barrel >> layer >> wedge >> side >> wafer >> half; // is >> v_x >> v_y >> v_z >> sh_x >> sh_y >> sh_z >> lo_x >> lo_y >> lo_z // >> n_x >> n_y >> n_z; // } return true; } private: Hep3Vector center,longv,shortv,normal; int CDF_code, barrel, layer, wedge, side, wafer, half; HepTransform3D tr; bool filled; }; class TranslateVectors { public: void readFile(ifstream& is); HepTransform3D makeAlignedTransform(AlDigiCode& ad); void printTransform(HepTransform3D& tr); void FillAlignment(); void FillBowAlignment(); void FillLadAlignment(); AlHolder* getAlignment() {return &ah; } AlHolder* getBowAlignment() {return &ahbow; } AlHolder* getLadAlignment() {return &ahlad; } AlTransform getAlTransform(HepTransform3D aln, HepTransform3D mis); private: VectorEntry entries[3][8][36][6]; // b,l,w,f AlHolder ah; AlHolder ahbow; AlHolder ahlad; }; //////////////////////////////////////////////// int main(int argc, char* argv[]){ TranslateVectors tv; if(argv[1]==NULL) { cout << "Usage: TranslateVectors in_file" << endl; } cout << " ignoring L00 for now" << endl; ifstream is(argv[1]); tv.readFile(is); is.close(); tv.FillAlignment(); tv.getAlignment()->writeToFile("vecwaf.txt"); tv.FillLadAlignment(); tv.getLadAlignment()->writeToFile("veclad.txt"); tv.FillBowAlignment(); tv.getBowAlignment()->writeToFile("vecbow.txt"); cout << "done" << endl; /* for(int i=0; i<8; i++) { if(tv.getSide()==0) { HepTransform3D mis = tv.makeMisalignedTransform(); HepTransform3D aln = tv.makeAlignedTransform(); tv.printTransform(aln); tv.printTransform(mis); AlDigiCode adc = tv.getAlDigiCode(); AlTransform a = tv.getLadderAl(); // **** is it ladder? ah.setLadder(adc, a.tx, a.ty, a.tz, a.ax, a.ay, a.az ); } } */ return 0; } //////////////////////////////////////////////// void TranslateVectors::readFile(ifstream& is) { bool stat=true; VectorEntry ve; stat = ve.readEntry(is); while(stat) { int b = ve.getBarrel(); int l = ve.getLayer(); int w = ve.getWedge(); int h = ve.getHalf(); int f = ve.getWafer(); int i; if(l==0) { i = h*2+f; } else if(l<=5) { i = (h==0? f: 3-f); } else { i = (h==0? 0: 5); // ISL is only half-ladder level } if(entries[b][l][w][i].getFilled()) { cout << "Duplicate found " << b <<" "<< l <<" "<< w <<" "<< i <<" "<< endl; } entries[b][l][w][i]=ve; if(l>5) { // ISL wafer=0 represent the whole half-ladder // z in that entry is the z of the central wafer, so correct all z's if(f!=0) cout << "found ISL wafer!=0 in readFile" << endl; HepTransform3D ttt = entries[b][l][w][i].getTransform(); double wp = Geom::waferZ(l); int i2; i2 = (h==0? 0 : 5 ); entries[b][l][w][i2].setTransform(ttt*HepTranslateZ3D(-wp)); i2 = (h==0? 1 : 4 ); entries[b][l][w][i2] = entries[b][l][w][i]; entries[b][l][w][i2].setWafer(f); entries[b][l][w][i2].setTransform(ttt); entries[b][l][w][i2].setFilled(true); i2 = (h==0? 2 : 3 ); entries[b][l][w][i2] = entries[b][l][w][i]; entries[b][l][w][i2].setWafer(f); entries[b][l][w][i2].setTransform(ttt*HepTranslateZ3D(wp)); entries[b][l][w][i2].setFilled(true); } stat = ve.readEntry(is); } } //////////////////////////////////////////////// void TranslateVectors::printTransform(HepTransform3D& tr) { Hep3Vector ta = tr.getTranslation(); HepRotation rt = tr.getRotation(); cout << endl << endl; cout << " " << setw(10) << ta.x() << " " << setw(10) << ta.y() << " " << setw(10) << ta.z() << endl << endl; cout << " " << setw(10) << rt.xx() << " " << setw(10) << rt.xy() << " " << setw(10) << rt.xz() << endl ; cout << " " << setw(10) << rt.yx() << " " << setw(10) << rt.yy() << " " << setw(10) << rt.yz() << endl ; cout << " " << setw(10) << rt.zx() << " " << setw(10) << rt.zy() << " " << setw(10) << rt.zz() << endl ; } //////////////////////////////////////////////// AlTransform TranslateVectors::getAlTransform(HepTransform3D aln, HepTransform3D mis) { // the alignment is applied first // mis = aln*tal HepTransform3D tal = (aln.inverse())*mis; //cout << " al trtans " << endl; //printTransform(tal); Hep3Vector v = tal.getTranslation(); HepRotation r = tal.getRotation(); // this decomposition only works for small angles, otherwise // more work would be needed for figuring out the right quadrant double sy = r.zx(); double ay = -asin(sy); double cy = cos(ay); double sx = r.zy()/cy; double sz = r.yx()/cy; double ax = asin(sx); double az = asin(sz); return AlTransform(v.x(),v.y(),v.z(),ax,ay,az); } //////////////////////////////////////////////// // fill ah AlHolder with input alignment into wafer positions only void TranslateVectors::FillAlignment() { AlDigiCode ad; ad.setResolution(AlDigiCode::LADDER); AlDigiCode ad2; ad2.setResolution(AlDigiCode::WAFER); for(int b=0; b<3; b++) { for(int l=0; l<=7; l++) { for(int w=0; w<36; w++) { if(entries[b][l][w][0].getFilled()) { //double vx=0.0,vy=0.0,vz=0.0,ax=0.0,ay=0.0,az=0.0; for(int i=0; i<6; i++) { if(entries[b][l][w][i].getFilled()) { int h,f; double wp = Geom::waferZ(l); if(l==0) { h = i/2; f = i-h*2; if(f==0) wp = -wp; } else if(l>=1 && l<=5) { h = i/2; f = (h==0?i : 3-i); if(i==0 || i==3) wp = -wp; } else if(l>=6) { h = i/3; f = (h==0?i : 5-i); if(f==0) { wp = -wp; } else if(f==1) { wp = 0.0; // center of three wafers } } ad.setPar(b,l,w,h); HepTransform3D hlNom = makeAlignedTransform(ad); HepTransform3D nom; nom = hlNom*HepTranslateZ3D(wp); HepTransform3D t = entries[b][l][w][i].getTransform(); //HepTransform3D del = (nom.inverse())*t; AlTransform adel = getAlTransform(nom, t); //vx += t.getTranslation().x(); //vy += t.getTranslation().y(); //vz += t.getTranslation().z(); ad2.setPar(b,l,w,h,f); ah.setWafer(ad2,adel.tx,adel.ty,adel.tz,adel.ax, adel.ay,adel.az,0.,0.,0.,0.); } // end if filled } // wafer loop } // end first wafer filled } // w } // l } // b } //////////////////////////////////////////////// // take AlHolder ah and extract only the bow values, write to an align file // this only addresses SVX void TranslateVectors::FillBowAlignment() { AlDigiCode ad; ad.setResolution(AlDigiCode::WAFER); for(int b=0; b<3; b++) { for(int l=1; l<6; l++) { for(int w=0; w<12; w++) { double x[4],xp[4]; double tx,ty,tz,ax,ay,az,dr,sTy,sTz,sAx; for(int i=0; i<4; i++) { if(entries[b][l][w][i].getFilled()) { int h = i/2; int f = (h==0? i : 3-i); ad.setPar(b,l,w,h,f); ah.getWafer(ad,tx,ty,tz,ax,ay,az,dr,sTy,sTz,sAx); x[i] = tx; xp[i] = (h==0? ay : -ay); } // end if filled } // end wafer loop // now find averages double x0 = x[0] - xp[0]*(7.43/2.0); double x1 = x[3] + xp[3]*(7.43/2.0); double xpl = (x1-x0)/(4.0*7.43); for(int i=0; i<4; i++) { x[i] = x[i] - (x0 + xpl*(double(i)+0.5)*7.43); xp[i] = xp[i] - xpl; } for(int i=0; i<4; i++) { int h = i/2; int f = (h==0? i : 3-i); tx=ty=tz=ax=ay=az=dr=0.0; tx = x[i]; ay = (h==0? xp[i] : -xp[i]); ad.setPar(b,l,w,h,f); ahbow.setWafer(ad,tx,ty,tz,ax,ay,az,dr,sTy,sTz,sAx); } } // w } // l } // b } //////////////////////////////////////////////// // take AlHolder ah and separate ladders and bows void TranslateVectors::FillLadAlignment() { AlDigiCode ad; double tx,ty,tz,ax,ay,az,dr,sTy,sTz,sAx; for(int b=0; b<3; b++) { for(int l=0; l<=7; l++) { for(int w=0; w<36; w++) { double x[6],xp[6],y[6],yp[6],z[6],zp[6]; bool filled = false; for(int i=0; i<6; i++) { //cout << " " << endl; //cout << " b l w i " << b << " " << l << " " << w << " " // << i << " " << i << endl; //cout << " b l w i " << b << " " << l << " " << w << " " // << i << " " << entries[b][l][w][i].getFilled() << endl; if(entries[b][l][w][i].getFilled()) { filled = true; int h,f; if(l==0) { h = i/2; f = i-h*2; } else if(l>=1 && l<=5) { h = i/2; f = (h==0?i : 3-i); } else if(l>=6) { h = i/3; f = (h==0?i : 5-i); } ad.setResolution(AlDigiCode::WAFER); ad.setPar(b,l,w,h,f); ah.getWafer(ad,tx,ty,tz,ax,ay,az,dr,sTy,sTz,sAx); if(l==0) { x[i] = tx; xp[i] = ay; y[i] = ty; yp[i] = -ax; z[i] = tz; zp[i] = az; } else { // for ISL, this only corrects the two hl relative // to each other, the flipping around z axis is left uncorrected. x[i] = tx; xp[i] = (h==0? ay : -ay); y[i] = (h==0? ty : -ty); yp[i] = -ax; z[i] = (h==0? tz : -tz); zp[i] = (h==0? az : -az); } } // end if filled } // end wafer loop if(filled) { // now find averages int nf = (l>=1 && l<=5? 4 : 6); double wafz; if(l==0) wafz = 7.84; // these are approximate, they are only used if(l>=1 && l<=5) wafz = 7.43; // to define the difference if(l==6) wafz = 6.9; // between wafr and ladder, which is arbitrary if(l==7) wafz = 7.48; double x0 = x[0] - xp[0]*(wafz/2.0); double x1 = x[nf-1] + xp[nf-1]*(wafz/2.0); double xpl = (x1-x0)/(nf*wafz); double xl = (x0+x1)/2.0; double y0 = y[0] - yp[0]*(wafz/2.0); double y1 = y[nf-1] + yp[nf-1]*(wafz/2.0); double ypl = (y1-y0)/(nf*wafz); double yl = (y0+y1)/2.0; double zl = (z[0]+z[1]+z[2]+z[3])/4.0; double zpl = (zp[0]+zp[1]+zp[2]+zp[3])/4.0; // find new wafer alignments for(int i=0; i=1 && l<=5) { h = i/2; f = (h==0?i : 3-i); } else if(l>=6) { h = i/3; f = (h==0?i : 5-i); } tx=ty=tz=ax=ay=az=dr=0.0; if(l==0) { tx = x[i]; ay = xp[i]; ty = y[i]; ax = -yp[i]; tz = z[i]; az = zp[i]; } else { // ISL was done in the frame with flip around z axis tx = x[i]; ay = (h==0? xp[i] : -xp[i]); ty = (h==0? y[i] : -y[i]); ax = -yp[i]; tz = (h==0? z[i] : -z[i]); az = (h==0? zp[i] : -zp[i]); } ad.setResolution(AlDigiCode::WAFER); ad.setPar(b,l,w,h,f); ahlad.setWafer(ad,tx,ty,tz,ax,ay,az,dr,0.,0.,0.); } // now load up the new ladder alignment tx=ty=tz=ax=ay=az=dr=0.0; if(l>=6 && w%2==1) { // ISL odd ladders are flipped around z tx = -xl; ay = -xpl; ty = -yl; ax = ypl; tz = zl; az = zpl; } else { tx = xl; ay = xpl; ty = yl; ax = -ypl; tz = zl; az = zpl; } ad.setResolution(AlDigiCode::LADDER); ad.setPar(b,l,w); ahlad.setLadder(ad,tx,ty,tz,ax,ay,az); } // filled } // w } // l } // b } //////////////////////////////////////////////// // return nominal half ladder position HepTransform3D TranslateVectors::makeAlignedTransform(AlDigiCode& ad) { const int N_BARRELS_MAX = 3; const int N_LAYERS_MAX = 8; const int NONEXISTENT = 0; const int N_READOUT_ENDS_MAX = 3; const double SVX_LADDER_PHI[N_BARRELS_MAX] [N_LAYERS_MAX]= {{ 0,0,0,0,0,0,+(360/48.0)*(M_PI/180.0),0.0 }, { 0,0,0,0,0,0,0.0,NONEXISTENT}, {NONEXISTENT,0,0,0,0,0,+(360/48.0)*(M_PI/180.0),0.0 }}; const double SVX_Z_CENTER[N_BARRELS_MAX] [N_LAYERS_MAX] [N_READOUT_ENDS_MAX]= { {{-39.7550, -8.3550, -24.0550}, {-38.8435,-23.9565, NONEXISTENT}, {-38.8425,-23.9575, NONEXISTENT}, {-38.8490,-23.9510, NONEXISTENT}, {-38.8435,-23.9565, NONEXISTENT}, {-38.8490,-23.9510, NONEXISTENT}, {-48.7265,-27.9905, NONEXISTENT}, {-78.2643,-55.8033,NONEXISTENT}}, {{ 8.3550,39.7550, 24.0550}, {-7.4435, 7.4435, NONEXISTENT}, {-7.4425, 7.4425, NONEXISTENT}, {-7.4490, 7.4490, NONEXISTENT}, {-7.4435, 7.4435, NONEXISTENT}, {-7.4490, 7.4490, NONEXISTENT}, {-10.2012,10.5348,NONEXISTENT}, {NONEXISTENT,NONEXISTENT,NONEXISTENT}}, {{NONEXISTENT,NONEXISTENT,NONEXISTENT}, {23.9565, 38.8435, NONEXISTENT}, {23.9575, 38.8425, NONEXISTENT}, {23.9510, 38.8490, NONEXISTENT}, {23.9565, 38.8435, NONEXISTENT}, {23.9510, 38.8490, NONEXISTENT}, {27.9965,48.7325,NONEXISTENT}, {55.7943,78.2553,NONEXISTENT}} }; const double SVX_RADIUS[2] [N_BARRELS_MAX] [N_LAYERS_MAX] = {{{1.35 ,2.9825,4.5575,7.0075,8.7075,10.6825,19.71,28.585}, {1.35 ,2.9825,4.5575,7.0075,8.7075,10.6825,22.585 ,NONEXISTENT}, {NONEXISTENT,2.9825,4.5575,7.0075,8.7075,10.6825,19.71,28.585}}, {{1.62 ,2.5325,4.1075,6.5075,8.2075,10.1325,20.215,28.99}, {1.62 ,2.5325,4.1075,6.5075,8.2075,10.1325,23.09,NONEXISTENT}, {NONEXISTENT,2.5325,4.1075,6.5075,8.2075,10.1325,20.215,28.99}} }; HepTransform3D transform; // this will be what is returned int l = ad.getLayer(); int b = ad.getBarrel(); int h = ad.getHalfLadder(); int p = ad.getWedge(); int f = ad.getWafer(); double zBarrel,dzHalfLadder; // the z center of the barrel if ( l == 0 ) { zBarrel = SVX_Z_CENTER[b][l][1]; } else { zBarrel = ( SVX_Z_CENTER[b][l][0] + SVX_Z_CENTER[b][l][1] ) /2.0; } // z distance from barrel center to half-ladder center dzHalfLadder = SVX_Z_CENTER[b][l][h] - zBarrel; // First, decide if we need to flip the ladder upsidedown. If it is // an ISL ladder, they alternate transeiver-up, transeiver-down // depending on which ledge they are mounted on. // ALL ISL have phi-strips // facing away from origin for even phi-addresses. // // If I've once again gotten this wrong, blame // Joel Goldstein, Work (630)840-6463, Beep (630)722-7569, // Home (773)486-0310, e-mail joelg@fnal.gov if ( l>=6 ) { if (p%2==1) { transform = HepRotateZ3D(M_PI)*transform; } } //move wafer to position along half ladder //if((l>=1 && l<=5) && f==1) { // transform = HepTranslate3D(0,0,3.715)*transform; //} // then flip it around if necessary - local y coordinates are along // phi readout direction, which varies if ( l==0 ) { if ( b==1 ) { transform = HepRotateX3D(M_PI)*transform; } } else { if ( h==1 ) { transform = HepRotateX3D(M_PI)*transform; } } // move the half ladder to the coordinates centered on full ladder transform = HepTranslate3D(0,0,dzHalfLadder)*transform; // if(includeAlignment) { // // apply the ladder alignment delta // HepTransform3D altr = _alignmentManager->getLadder(d); // transform = altr * transform; // } // now move to the coordinates with origin at the center of the barrel // move to proper radius transform = HepTranslate3D(SVX_RADIUS[p%2][b][l],0,0)*transform; // and the proper phi int nPhi; if (l==6) { if (b==1) { nPhi=28; } else { nPhi= 24; } } else if (l==7) { nPhi = 36; } else { nPhi = 12; } double dphi = p * 2.0 * M_PI / nPhi; dphi = dphi + SVX_LADDER_PHI[b][l]; transform = HepRotateZ3D(dphi) * transform; //if(includeAlignment) { // // apply the barrel alignment delta // HepTransform3D altr = _alignmentManager->getBarrel(d); // transform = altr *transform; //} // translate barrel to proper Z location. transform = HepTranslate3D(0,0,zBarrel) * transform; //if(includeAlignment) { // // apply the spaceframe alignment delta // HepTransform3D altr = _alignmentManager->getFrame(); // transform = altr * transform; //} return transform; } // end make transform