+
+//_____________________________________________________________________________
+void AliTOFAlignment::AlignFromSurveyABD(Int_t iSM)
+{
+
+ //From Survey data, derive the needed transformations to get the
+ //Alignment Objects.
+ //Again, highly "inspired" to Raffaele's example...
+ //we use FM A,B,D
+
+ Double_t ngA[3], ngB[3], ngD[3];// real FM point coord., global RS
+
+ // Get the 'realistic' input from the Survey Matrix
+ for(Int_t coord=0;coord<3;coord++){
+ ngA[coord]= fCombFMData[iSM*4][coord*2];
+ ngB[coord]= fCombFMData[iSM*4+1][coord*2];
+ ngD[coord]= fCombFMData[iSM*4+3][coord*2];
+ }
+
+ printf("\n\n******Survey analysis for TOF SuperModule ************** %i \n",iSM);
+
+ // From the new fiducial marks coordinates derive back the
+ // new global position of the surveyed volume
+ //*** What follows is the actual survey-to-alignment procedure
+
+ Double_t ab[3], ad[3], n[3];
+ Double_t plane[4], s=1.;
+
+ // first vector on the plane of the fiducial marks
+ for(Int_t i=0;i<3;i++){
+ ab[i] = (ngB[i] - ngA[i]);
+ }
+
+ // second vector on the plane of the fiducial marks
+ for(Int_t i=0;i<3;i++){
+ ad[i] = (ngD[i] - ngA[i]);
+ }
+
+ // vector normal to the plane of the fiducial marks obtained
+ // as cross product of the two vectors on the plane d0^d1
+ n[0] = (ab[1] * ad[2] - ab[2] * ad[1]);
+ n[1] = (ab[2] * ad[0] - ab[0] * ad[2]);
+ n[2] = (ab[0] * ad[1] - ab[1] * ad[0]);
+
+ Double_t sizen = TMath::Sqrt( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] );
+ if(sizen>1.e-8){
+ s = Double_t(1.)/sizen ; //normalization factor
+ }else{
+ AliInfo("Problem in normalizing the vector");
+ }
+
+ // plane expressed in the hessian normal form, see:
+ // http://mathworld.wolfram.com/HessianNormalForm.html
+ // the first three are the coordinates of the orthonormal vector
+ // the fourth coordinate is equal to the distance from the origin
+
+ for(Int_t i=0;i<3;i++){
+ plane[i] = n[i] * s;
+ }
+ plane[3] = ( plane[0] * ngA[0] + plane[1] * ngA[1] + plane[2] * ngA[2] );
+
+ // The center of the square with fiducial marks as corners
+ // as the middle point of one diagonal - md
+ // Used below to get the center - orig - of the surveyed box
+
+ Double_t orig[3], md[3];
+ for(Int_t i=0;i<3;i++){
+ md[i] = (ngB[i] + ngD[i]) * 0.5;
+ }
+
+ // The center of the box, gives the global translation
+ for(Int_t i=0;i<3;i++){
+ orig[i] = md[i] - plane[i]*fgkZFM;
+ }
+
+ // get local directions needed to write the global rotation matrix
+ // for the surveyed volume by normalising vectors ab and bc
+ Double_t sx = TMath::Sqrt(ab[0]*ab[0] + ab[1]*ab[1] + ab[2]*ab[2]);
+ if(sx>1.e-8){
+ for(Int_t i=0;i<3;i++){
+ ab[i] /= sx;
+ }
+ }
+ Double_t sy = TMath::Sqrt(ad[0]*ad[0] + ad[1]*ad[1] + ad[2]*ad[2]);
+ if(sy>1.e-8){
+ for(Int_t i=0;i<3;i++){
+ ad[i] /= sy;
+ }
+ }
+ Double_t rot[9] = {ab[0],ad[0],plane[0],ab[1],ad[1],plane[1],ab[2],ad[2],plane[2]};
+ // the Aligned matrix for the current TOF SM in the Global RS, as derived from Survey:
+ TGeoHMatrix ng;
+ ng.SetTranslation(orig);
+ ng.SetRotation(rot);
+ printf("\n\n**** The Misaligned Matrix in GRS, as from Survey data ***\n");
+ ng.Print();
+
+ // Calculate the delta transformation wrt Ideal geometry
+ // (Should be gdelta.rot ==I and gdelta.tr=0 if no misalignment is applied.)
+
+ printf("\n\n**** The ideal matrix ***\n");
+ fTOFMatrixId[iSM]->Print();
+
+ TGeoHMatrix gdelta =fTOFMatrixId[iSM]->Inverse();
+ printf("\n\n**** The inverse of the ideal matrix ***\n");
+ gdelta.Print();
+
+ gdelta.MultiplyLeft(&ng);
+ printf("\n\n**** The Delta Matrix in GRS, as from Survey data ***\n");
+ gdelta.Print(); //global delta trasformation
+
+ // Now Write the Alignment Objects....
+ Int_t index=0; //let all SM modules have index=0
+ AliGeomManager::ELayerID layer = AliGeomManager::kInvalidLayer;
+ UShort_t dvoluid = AliGeomManager::LayerToVolUID(layer,index); //dummy vol id
+ TString symname(Form("TOF/sm%02d",iSM));
+ AliAlignObjMatrix* o = new AliAlignObjMatrix(symname.Data(),dvoluid,gdelta,kTRUE);
+ fTOFAlignObjArray->Add(o);
+
+ }
+//_____________________________________________________________________________
+void AliTOFAlignment::AlignFromSurveyACD(Int_t iSM)
+{
+ //From Survey data, derive the needed transformations to get the
+ //Alignment Objects.
+ //Again, highly "inspired" to Raffaele's example...
+ //we use FM A,C,D
+
+
+ Double_t ngA[3], ngC[3], ngD[3];// real FM point coord., global RS
+
+ // Get the 'realistic' input from the Survey Matrix
+ for(Int_t coord=0;coord<3;coord++){
+ ngA[coord]= fCombFMData[iSM*4][coord*2];
+ ngC[coord]= fCombFMData[iSM*4+2][coord*2];
+ ngD[coord]= fCombFMData[iSM*4+3][coord*2];
+ }
+
+ printf("\n\n******Survey analysis for TOF SuperModule ************** %i \n",iSM);
+
+ // From the new fiducial marks coordinates derive back the
+ // new global position of the surveyed volume
+ //*** What follows is the actual survey-to-alignment procedure
+
+ Double_t cd[3], ad[3], n[3];
+ Double_t plane[4], s=1.;
+
+ // first vector on the plane of the fiducial marks
+ for(Int_t i=0;i<3;i++){
+ cd[i] = (ngC[i] - ngD[i]);
+ }
+
+ // second vector on the plane of the fiducial marks
+ for(Int_t i=0;i<3;i++){
+ ad[i] = (ngD[i] - ngA[i]);
+ }
+
+ // vector normal to the plane of the fiducial marks obtained
+ // as cross product of the two vectors on the plane d0^d1
+ n[0] = (ad[1] * cd[2] - ad[2] * cd[1]);
+ n[1] = (ad[2] * cd[0] - ad[0] * cd[2]);
+ n[2] = (ad[0] * cd[1] - ad[1] * cd[0]);
+
+ Double_t sizen = TMath::Sqrt( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] );
+ if(sizen>1.e-8){
+ s = Double_t(1.)/sizen ; //normalization factor
+ }else{
+ AliInfo("Problem in normalizing the vector");
+ }
+
+ // plane expressed in the hessian normal form, see:
+ // http://mathworld.wolfram.com/HessianNormalForm.html
+ // the first three are the coordinates of the orthonormal vector
+ // the fourth coordinate is equal to the distance from the origin
+
+ for(Int_t i=0;i<3;i++){
+ plane[i] = n[i] * s;
+ }
+ plane[3] = ( plane[0] * ngA[0] + plane[1] * ngA[1] + plane[2] * ngA[2] );
+
+ // The center of the square with fiducial marks as corners
+ // as the middle point of one diagonal - md
+ // Used below to get the center - orig - of the surveyed box
+
+ Double_t orig[3], md[3];
+ for(Int_t i=0;i<3;i++){
+ md[i] = (ngA[i] + ngC[i]) * 0.5;
+ }
+
+ // The center of the box, gives the global translation
+ for(Int_t i=0;i<3;i++){
+ orig[i] = md[i] + plane[i]*fgkZFM;
+ }
+
+ // get local directions needed to write the global rotation matrix
+ // for the surveyed volume by normalising vectors ab and bc
+ Double_t sx = TMath::Sqrt(ad[0]*ad[0] + ad[1]*ad[1] + ad[2]*ad[2]);
+ if(sx>1.e-8){
+ for(Int_t i=0;i<3;i++){
+ ad[i] /= sx;
+ }
+ }
+ Double_t sy = TMath::Sqrt(cd[0]*cd[0] + cd[1]*cd[1] + cd[2]*cd[2]);
+ if(sy>1.e-8){
+ for(Int_t i=0;i<3;i++){
+ cd[i] /= sy;
+ }
+ }
+ Double_t rot[9] = {cd[0],ad[0],-plane[0],cd[1],ad[1],-plane[1],cd[2],ad[2],-plane[2]};
+ // the Aligned matrix for the current TOF SM in the Global RS, as derived from Survey:
+ TGeoHMatrix ng;
+ ng.SetTranslation(orig);
+ ng.SetRotation(rot);
+ printf("\n\n**** The Misaligned Matrix in GRS, as from Survey data ***\n");
+ ng.Print();
+
+ // Calculate the delta transformation wrt Ideal geometry
+ // (Should be gdelta.rot ==I and gdelta.tr=0 if no misalignment is applied.)
+
+ printf("\n\n**** The ideal matrix ***\n");
+ fTOFMatrixId[iSM]->Print();
+
+ TGeoHMatrix gdelta =fTOFMatrixId[iSM]->Inverse();
+ printf("\n\n**** The inverse of the ideal matrix ***\n");
+ gdelta.Print();
+
+ gdelta.MultiplyLeft(&ng);
+ printf("\n\n**** The Delta Matrix in GRS, as from Survey data ***\n");
+ gdelta.Print(); //global delta trasformation
+
+ // Now Write the Alignment Objects....
+ Int_t index=0; //let all SM modules have index=0
+ AliGeomManager::ELayerID layer = AliGeomManager::kInvalidLayer;
+ UShort_t dvoluid = AliGeomManager::LayerToVolUID(layer,index); //dummy vol id
+ TString symname(Form("TOF/sm%02d",iSM));
+ AliAlignObjMatrix* o = new AliAlignObjMatrix(symname.Data(),dvoluid,gdelta,kTRUE);
+ fTOFAlignObjArray->Add(o);
+ }
+
+//___________________________________________________________________________
+void AliTOFAlignment::AlignFromSurveyBCD(Int_t iSM)
+{
+ //From Survey data, derive the needed transformations to get the
+ //Alignment Objects.
+ //Again, highly "inspired" to Raffaele's example...
+ //we use FM B,C,D
+
+ Double_t ngB[3], ngC[3], ngD[3];// real FM point coord., global RS
+
+
+ // Get the 'realistic' input from the Survey Matrix
+ for(Int_t coord=0;coord<3;coord++){
+ ngB[coord]= fCombFMData[iSM*4+1][coord*2];
+ ngC[coord]= fCombFMData[iSM*4+2][coord*2];
+ ngD[coord]= fCombFMData[iSM*4+3][coord*2];
+ }
+
+ printf("\n\n******Survey analysis for TOF SuperModule ************** %i \n",iSM);
+
+ // From the new fiducial marks coordinates derive back the
+ // new global position of the surveyed volume
+ //*** What follows is the actual survey-to-alignment procedure
+
+ Double_t cd[3], bc[3], n[3];
+ Double_t plane[4], s=1.;
+
+ // first vector on the plane of the fiducial marks
+ for(Int_t i=0;i<3;i++){
+ cd[i] = (ngC[i] - ngD[i]);
+ }
+
+ // second vector on the plane of the fiducial marks
+ for(Int_t i=0;i<3;i++){
+ bc[i] = (ngC[i] - ngB[i]);
+ }
+
+ // vector normal to the plane of the fiducial marks obtained
+ // as cross product of the two vectors on the plane d0^d1
+ n[0] = (bc[1] * cd[2] - bc[2] * cd[1]);
+ n[1] = (bc[2] * cd[0] - bc[0] * cd[2]);
+ n[2] = (bc[0] * cd[1] - bc[1] * cd[0]);
+
+ Double_t sizen = TMath::Sqrt( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] );
+ if(sizen>1.e-8){
+ s = Double_t(1.)/sizen ; //normalization factor
+ }else{
+ AliInfo("Problem in normalizing the vector");
+ }
+
+ // plane expressed in the hessian normal form, see:
+ // http://mathworld.wolfram.com/HessianNormalForm.html
+ // the first three are the coordinates of the orthonormal vector
+ // the fourth coordinate is equal to the distance from the origin
+
+ for(Int_t i=0;i<3;i++){
+ plane[i] = n[i] * s;
+ }
+ plane[3] = ( plane[0] * ngB[0] + plane[1] * ngB[1] + plane[2] * ngB[2] );
+
+ // The center of the square with fiducial marks as corners
+ // as the middle point of one diagonal - md
+ // Used below to get the center - orig - of the surveyed box
+
+ Double_t orig[3], md[3];
+ for(Int_t i=0;i<3;i++){
+ md[i] = (ngB[i] + ngD[i]) * 0.5;
+ }
+
+ // The center of the box, gives the global translation
+ for(Int_t i=0;i<3;i++){
+ orig[i] = md[i] + plane[i]*fgkZFM;
+ }
+
+ // get local directions needed to write the global rotation matrix
+ // for the surveyed volume by normalising vectors ab and bc
+ Double_t sx = TMath::Sqrt(cd[0]*cd[0] + cd[1]*cd[1] + cd[2]*cd[2]);
+ if(sx>1.e-8){
+ for(Int_t i=0;i<3;i++){
+ cd[i] /= sx;
+ }
+ }
+ Double_t sy = TMath::Sqrt(bc[0]*bc[0] + bc[1]*bc[1] + bc[2]*bc[2]);
+ if(sy>1.e-8){
+ for(Int_t i=0;i<3;i++){
+ bc[i] /= sy;
+ }
+ }
+ Double_t rot[9] = {cd[0],bc[0],-plane[0],cd[1],bc[1],-plane[1],cd[2],bc[2],-plane[2]};
+ // the Aligned matrix for the current TOF SM in the Global RS, as derived from Survey:
+ TGeoHMatrix ng;
+ ng.SetTranslation(orig);
+ ng.SetRotation(rot);
+ printf("\n\n**** The Misaligned Matrix in GRS, as from Survey data ***\n");
+ ng.Print();
+
+ // Calculate the delta transformation wrt Ideal geometry
+ // (Should be gdelta.rot ==I and gdelta.tr=0 if no misalignment is applied.)
+
+ printf("\n\n**** The ideal matrix ***\n");
+ fTOFMatrixId[iSM]->Print();
+
+ TGeoHMatrix gdelta =fTOFMatrixId[iSM]->Inverse();
+ printf("\n\n**** The inverse of the ideal matrix ***\n");
+ gdelta.Print();
+
+ gdelta.MultiplyLeft(&ng);
+ printf("\n\n**** The Delta Matrix in GRS, as from Survey data ***\n");
+ gdelta.Print(); //global delta trasformation
+
+ // Now Write the Alignment Objects....
+ Int_t index=0; //let all SM modules have index=0
+ AliGeomManager::ELayerID layer = AliGeomManager::kInvalidLayer;
+ UShort_t dvoluid = AliGeomManager::LayerToVolUID(layer,index); //dummy vol id
+ TString symname(Form("TOF/sm%02d",iSM));
+ AliAlignObjMatrix* o = new AliAlignObjMatrix(symname.Data(),dvoluid,gdelta,kTRUE);
+ fTOFAlignObjArray->Add(o);
+ }
+
+