-I$ALICE_ROOT/TPC -I$ALICE_ROOT/ITS -I$ALICE_ROOT/TRD -I$ALICE_ROOT/TOF -I$ALICE_ROOT/RAW -I$ALICE_ROOT/PWG1 -I$ALICE_ROOT/STAT -I$ALICE_ROOT/TPC/Base -I$ALICE_ROOT/TPC/Calib");
.L $ALICE_ROOT/TPC/Base/test/UnitTest.C+
- UnitTestAliTPCCalPadTree();
- TestCorrection_AliTPCExBTwistAddCorrectionCompact();
- TestCorrection_AliTPCFCVoltError3DAddCorrectionCompact();
- TestCorrection_AliTPCRocVoltError3DAddCorrectionCompact();
- TestCorrection_AliTPCBoundaryVoltErrorAddCorrectionCompact();
+G UnitTestAliTPCCalPadTree();
+ TestCorrection_AliTPCCorrection_AddCorrectionCompact();
*/
#include "AliTPCFCVoltError3D.h"
#include "AliTPCROCVoltError3D.h"
#include "AliTPCBoundaryVoltError.h"
-
+#include "AliTPCCalibGlobalMisalignment.h"
+#include "AliCDBEntry.h"
+#include "TStopwatch.h"
+#include "TGeoMatrix.h"
+
//
// PARAMETERS to set from outside:
//
//
//
+Bool_t TestCorrection_AliTPCCorrection_AddCorrectionCompact();
+Bool_t TestCorrection_AliTPCExBTwistAddCorrectionCompact();
+Bool_t TestCorrection_AliTPCFCVoltError3DAddCorrectionCompact();
+Bool_t TestCorrection_AliTPCRocVoltError3DAddCorrectionCompact();
+Bool_t TestCorrection_AliTPCBoundaryVoltErrorAddCorrectionCompact();
+Bool_t TestCorrection_AliTPCCalibGlobalMisalignmentAddCorrectionCompact();
+Bool_t TestCorrection_AliTPCComposedCorrectionAddCorrectionCompact();
+
void UnitTestAliTPCCalPadTree(){
//
AliTPCExBTwist *twistY = new AliTPCExBTwist;
twistX->SetXTwist(0.001); // 1 mrad twist in x
twistY->SetYTwist(0.001); // 1 mrad twist in x
- isOK[0]&=compCorrTwist->AddCorrectionCompact(twistX,1);
- isOK[0]&=compCorrTwist->AddCorrectionCompact(twistY,1);
+ isOK[0]&=compCorrTwist->AddCorrectionCompact(twistX,0.5);
+ isOK[0]&=compCorrTwist->AddCorrectionCompact(twistY,0.5);
+ isOK[0]&=compCorrTwist->AddCorrectionCompact(twistX,0.5);
+ isOK[0]&=compCorrTwist->AddCorrectionCompact(twistY,0.5);
isOK[0]&=compCorrTwist->AddCorrectionCompact(twistY,-1);
isOK[0]&=compCorrTwist->AddCorrectionCompact(twistX,-1);
isOK[1]=compCorrTwist->GetCorrections()->GetEntries()==1;
+
AliTPCExBTwist *twistRes=0;
if (isOK[1]==kFALSE){
isOK[2]=kFALSE;
corr1->SetCopperRodShiftC(isec,TMath::Sin(TMath::Pi()*isec/36),kFALSE);
}
//
- isOK[0]&=compCorrComp->AddCorrectionCompact(corr0,1);
- isOK[0]&=compCorrComp->AddCorrectionCompact(corr1,1);
+ isOK[0]&=compCorrComp->AddCorrectionCompact(corr0,0.5);
+ isOK[0]&=compCorrComp->AddCorrectionCompact(corr1,0.5);
+ isOK[0]&=compCorrComp->AddCorrectionCompact(corr0,0.5);
+ isOK[0]&=compCorrComp->AddCorrectionCompact(corr1,0.5);
isOK[0]&=compCorrComp->AddCorrectionCompact(corr1,-1);
isOK[0]&=compCorrComp->AddCorrectionCompact(corr0,-1);
isOK[1]=compCorrComp->GetCorrections()->GetEntries()==1;
matrixDz*=0.5;
corr1->SetROCData(&matrixDz);
//
- isOK[0]&=compCorrROCVoltError3D->AddCorrectionCompact(corr0,1);
- isOK[0]&=compCorrROCVoltError3D->AddCorrectionCompact(corr1,1);
+ isOK[0]&=compCorrROCVoltError3D->AddCorrectionCompact(corr0,0.5);
+ isOK[0]&=compCorrROCVoltError3D->AddCorrectionCompact(corr1,0.5);
+ isOK[0]&=compCorrROCVoltError3D->AddCorrectionCompact(corr0,0.5);
+ isOK[0]&=compCorrROCVoltError3D->AddCorrectionCompact(corr1,0.5);
isOK[0]&=compCorrROCVoltError3D->AddCorrectionCompact(corr1,-1);
isOK[0]&=compCorrROCVoltError3D->AddCorrectionCompact(corr0,-1);
isOK[1]=compCorrROCVoltError3D->GetCorrections()->GetEntries()==1;
corr0->SetBoundariesA(boundaries);
corr1->SetBoundariesA(boundaries);
//
- isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr0,1);
- isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr1,1);
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr0,0.5);
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr1,0.5);
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr0,0.5);
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr1,0.5);
isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr1,-1);
isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr0,-1);
isOK[1]=compCorrBoundaryVoltError->GetCorrections()->GetEntries()==1;
}
return res;
}
+
+
+
+
+
+Bool_t TestCorrection_AliTPCCalibGlobalMisalignmentAddCorrectionCompact(){
+ //
+ // AliTPCCalibGlobalMisalignmentAddCorrectionCompact
+ // Invariant used in test is not exact it is only approximate - as matrix multiplication is not comulative
+ //
+ //
+ const Float_t kEpsilon=0.0001;
+ Bool_t isOK[10]={kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE};
+ Double_t delta[3]={0.01,0.02,0.03};
+
+ AliTPCComposedCorrection *compCorrBoundaryVoltError = new AliTPCComposedCorrection();
+ AliTPCCalibGlobalMisalignment *corr0 = new AliTPCCalibGlobalMisalignment;
+ AliTPCCalibGlobalMisalignment *corr1 = new AliTPCCalibGlobalMisalignment;
+ AliTPCCalibGlobalMisalignment *corr2 = new AliTPCCalibGlobalMisalignment;
+ TObjArray sectorAlign(72);
+
+ TGeoHMatrix *hmatrix0 = new TGeoHMatrix;
+ TGeoHMatrix *hmatrix1 = new TGeoHMatrix;
+ hmatrix0->RotateX(TMath::RadToDeg()*0.0001);
+ hmatrix0->RotateY(TMath::RadToDeg()*0.0002);
+ hmatrix0->RotateZ(TMath::RadToDeg()*0.0003);
+ hmatrix1->SetTranslation(delta);
+ for (Int_t isec=0; isec<72; isec++){
+ if ((isec%2)==0) sectorAlign.AddAt(hmatrix0,isec);
+ if ((isec%2)==1) sectorAlign.AddAt(hmatrix1,isec);
+ }
+ corr0->SetAlignGlobal(hmatrix0);
+ corr1->SetAlignGlobal(hmatrix1);
+ corr0->SetAlignGlobalDelta(hmatrix1);
+ corr1->SetAlignGlobalDelta(hmatrix0);
+ corr2->SetAlignSectors(§orAlign);
+ //
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr0,0.5);
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr1,0.5);
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr0,0.5);
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr1,0.5);
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr0,-1);
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr1,-1);
+ //
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr2,1);
+ isOK[0]&=compCorrBoundaryVoltError->AddCorrectionCompact(corr2,-1);
+ //
+ //
+ isOK[1]=compCorrBoundaryVoltError->GetCorrections()->GetEntries()==1;
+ AliTPCCalibGlobalMisalignment *corrRes=0;
+ if (isOK[1]==kFALSE){
+ isOK[2]=kFALSE;
+ isOK[3]=kFALSE;
+ isOK[4]=kFALSE;
+ }else{
+ corrRes= dynamic_cast<AliTPCCalibGlobalMisalignment *>(compCorrBoundaryVoltError->GetSubCorrection(0));
+ if (corrRes==NULL){
+ isOK[2]=kFALSE;
+ isOK[3]=kFALSE;
+ isOK[4]=kFALSE;
+ }else{
+ for (Int_t itrans=0; itrans<3; itrans++){
+ isOK[2+itrans]&=TMath::Abs(corrRes->GetAlignGlobal()->GetTranslation()[itrans])<kEpsilon;
+ for (Int_t isec=0; isec<72; isec++){
+ isOK[2+itrans]&=TMath::Abs(((TGeoHMatrix*)(corrRes->GetAlignSectors()->At(isec)))->GetTranslation()[itrans])<kEpsilon;
+ }
+ }
+ corrRes->GetAlignGlobal()->Print();
+ corrRes->GetAlignSectors()->At(0)->Print();
+ corrRes->GetAlignSectors()->At(1)->Print();
+ }
+ }
+ Bool_t res=kTRUE;
+ for (Int_t i=0; i<5; i++) res&=isOK[i];
+ {
+ if (isOK[0]==kFALSE){
+ ::Error("TestCorrection_AddCorrectionCompact","AliTPCCalibGlobalMisalignment -ADD FAILED");
+ }else{
+ ::Info("TestCorrection_AddCorrectionCompact","AliTPCCalibGlobalMisalignment -ADD OK");
+ }
+ if (isOK[1]==kFALSE){
+ ::Error("TestCorrection_AddCorrectionCompact","AliTPCCalibGlobalMisalignment - wrong entries FAILED");
+ }else{
+ ::Info("TestCorrection_AddCorrectionCompact","AliTPCCalibGlobalMisalignment - entries OK");
+ }
+ if (isOK[2]==kFALSE || isOK[3]==kFALSE ||isOK[4]==kFALSE ){
+ ::Error("TestCorrection_AddCorrectionCompact","AliTPCCalibGlobalMisalignment - inconsitent entries FAILED");
+ }else{
+ ::Info("TestCorrection_AddCorrectionCompact","AliTPCCalibGlobalMisalignment - consistent entries OK");
+ }
+ }
+ return res;
+}
+
+Bool_t TestCorrection_AliTPCCorrection_AddCorrectionCompact(){
+ //
+ //
+ //
+ TestCorrection_AliTPCExBTwistAddCorrectionCompact();
+ TestCorrection_AliTPCFCVoltError3DAddCorrectionCompact();
+ TestCorrection_AliTPCRocVoltError3DAddCorrectionCompact();
+ TestCorrection_AliTPCBoundaryVoltErrorAddCorrectionCompact();
+ TestCorrection_AliTPCCalibGlobalMisalignmentAddCorrectionCompact();
+}
+
+
+Bool_t TestCorrection_AliTPCComposedCorrectionAddCorrectionCompact(){
+ //
+ // Tests of AliTPCComposedCorrection
+ // 1.) Make linear combination correction example using weights.
+ // Test correction checking invariant inverse x orig (there are simpler way to do inversion using AliTPCInverseCorrection)
+ //
+ // 2.) Make compact for of the Composed correction. Test correction checking invariant inverse x orig
+ //
+ const Int_t npointsTest=10000;
+ const Float_t kEpsilon=0.0001; // using Floating point precission
+
+ //
+ // 0.) Read an input OCDB entry
+ //
+ TFile * f = TFile::Open("$ALICE_OCDB/alice/data/2010/OCDB/TPC/Calib/Correction/Run0_999999999_v8_s0.root");
+ AliCDBEntry * entry=(AliCDBEntry*)f->Get("AliCDBEntry");
+ TObjArray * corrArray = (TObjArray *)entry->GetObject();
+ AliTPCComposedCorrection *compInput = (AliTPCComposedCorrection *)corrArray->At(0);
+ //
+ // 1.) Make linear combination correction example using weights.
+ // Test correction checking invariant inverse x orig (there are simpler way to do inversion using AliTPCInverseCorrection)
+ AliTPCComposedCorrection *compInverse = new AliTPCComposedCorrection();
+ Bool_t isOK1[10]={kTRUE};
+ TObjArray * collection= dynamic_cast<TObjArray*>(compInput->GetCorrections());
+ Int_t entries = collection->GetEntries();
+ TVectorD weights(entries+1);
+ for (Int_t i=0; i<entries+1; i++) weights[i]=-1.0;
+ weights[0]=1.;
+ TObjArray * arrayInvariant = new TObjArray(entries+1);
+ arrayInvariant->AddLast(compInput);
+ for (Int_t i=0; i<entries; i++) arrayInvariant->AddLast( collection->At(i));
+ compInverse->SetCorrections( arrayInvariant);
+ compInverse->SetWeights(&weights);
+ compInverse->AddVisualCorrection(compInverse,1);
+ compInput->AddVisualCorrection(compInput,2);
+ TF1 finv1("finv1","AliTPCCorrection::GetCorrXYZ(x,x,100,0,1)",85,245);
+ //
+ TVectorD vecCompInverse(npointsTest);
+ for (Int_t icoord=0; icoord<3; icoord++){
+ for (Int_t ipoint=0; ipoint<npointsTest; ipoint++){
+ Double_t r= 85.+gRandom->Rndm()*150;
+ Double_t phi= gRandom->Rndm()*TMath::TwoPi();
+ Double_t z=500*(gRandom->Rndm()-0.5);
+ vecCompInverse[ipoint]=AliTPCCorrection::GetCorrXYZ(r*TMath::Cos(phi),r*TMath::Sin(phi),z, icoord, 1);
+ }
+ Double_t rms=TMath::RMS(npointsTest,vecCompInverse.GetMatrixArray());
+ Double_t mean=TMath::Mean(npointsTest,vecCompInverse.GetMatrixArray());
+ isOK1[icoord]=TMath::Abs(rms)<kEpsilon;
+ isOK1[icoord]&=TMath::Abs(mean)<kEpsilon;
+ }
+ if (isOK1[0]==kFALSE || isOK1[1]==kFALSE ||isOK1[2]==kFALSE ){
+ ::Error("TestCorrection_AddCorrectionCompact",TString::Format("AliTPCComposedCorrection - Test1 (%d,%d,%d) FAILED",isOK1[0], isOK1[1],isOK1[2]).Data());
+ }else{
+ ::Info("TestCorrection_AddCorrectionCompact","AliTPCComposedCorrection - Test1 OK");
+ }
+ //
+ // 2.) Make compact for of the Composed correction. Test correction checking invariant inverse x orig
+ // This take time - dostortion has to be recalculated
+ AliTPCComposedCorrection *compOutInverseCompact = new AliTPCComposedCorrection();
+ compOutInverseCompact->AddCorrectionCompact(compInput,-1);
+ compOutInverseCompact->SetOmegaTauT1T2(0,1,1);
+ compInput->SetOmegaTauT1T2(0,1,1);
+ compOutInverseCompact->AddVisualCorrection(compOutInverseCompact,10);
+ compInput->AddVisualCorrection(compInput,2);
+ TStopwatch timer;
+ //
+ TF1 fcomp("fcomp","AliTPCCorrection::GetCorrXYZ(x,x,100,0,10)",85,245);
+ TF1 forig("forig","-AliTPCCorrection::GetCorrXYZ(x,x,100,0,2)",85,245);
+ TF1 fdiff("fdiff","AliTPCCorrection::GetCorrXYZ(x,x,100,0,10)+AliTPCCorrection::GetCorrXYZ(x,x,100,0,2)",85,245);
+ timer.Print();
+
+
+ return kTRUE;
+}
delete fArraySector; // sector matrices
}
+
+
+Bool_t AliTPCCalibGlobalMisalignment::AddCorrectionCompact(AliTPCCorrection* corr, Double_t weight){
+ //
+ // Add correction and make them compact
+ // Assumptions:
+ // - origin of distortion/correction are additive
+ // - only correction ot the same type supported ()
+ if (corr==NULL) {
+ //AliError("Zerro pointer - correction");
+ return kFALSE;
+ }
+ AliTPCCalibGlobalMisalignment* corrC = dynamic_cast<AliTPCCalibGlobalMisalignment *>(corr);
+ if (corrC == NULL) {
+ //AliError(TString::Format("Inconsistent class types: %s\%s",IsA()->GetName(),corr->IsA()->GetName()).Data());
+ return kFALSE;
+ }
+ //
+ AliTPCCalibGlobalMisalignment & add = *corrC;
+ fXShift+=weight*add.fXShift; // Shift in global X [cm]
+ fYShift+=weight*add.fYShift; // Shift in global Y [cm]
+ fZShift+=weight*add.fZShift; // Shift in global Z [cm]
+
+ fRotPhiA+=weight*add.fRotPhiA; // simple rotation of A side read-out plane around the Z axis [rad]
+ fRotPhiC+=weight*add.fRotPhiC; // simple rotation of C side read-out plane around the Z axis [rad]
+ fdRPhiOffsetA+=weight*add.fdRPhiOffsetA; // add a constant offset of dRPhi (or local Y) in [cm]: purely for calibration purposes!
+ fdRPhiOffsetC+=weight*add.fdRPhiOffsetC; // add a constant offset of dRPhi (or local Y) in [cm]: purely for calibration purposes!
+ //
+ // Quadrant alignment
+ //
+ if (add.fQuadrantQ0) {
+ if (fQuadrantQ0) fQuadrantQ0->Add(weight*(*(add.fQuadrantQ0)));
+ if (!fQuadrantQ0) {
+ fQuadrantQ0 = (TVectorD*)(add.fQuadrantQ0->Clone());
+ (*fQuadrantQ0)*=weight;
+ }
+ }
+ if (add.fQuadrantRQ0) {
+ if (fQuadrantRQ0) fQuadrantRQ0->Add(weight*(*(add.fQuadrantRQ0)));
+ if (!fQuadrantRQ0) {
+ fQuadrantRQ0 = (TVectorD*)(add.fQuadrantRQ0->Clone());
+ (*fQuadrantRQ0)*=weight;
+ }
+ }
+ //
+ if (add.fQuadrantQ1) {
+ if (fQuadrantQ1) fQuadrantQ1->Add(weight*(*(add.fQuadrantQ1)));
+ if (!fQuadrantQ1) {
+ fQuadrantQ1 = (TVectorD*)(add.fQuadrantQ1->Clone());
+ (*fQuadrantQ1)*=weight;
+ }
+ }
+ if (add.fQuadrantRQ1) {
+ if (fQuadrantRQ1) fQuadrantRQ1->Add(weight*(*(add.fQuadrantRQ1)));
+ if (!fQuadrantRQ1) {
+ fQuadrantRQ1 = (TVectorD*)(add.fQuadrantRQ1->Clone());
+ (*fQuadrantRQ1)*=weight;
+ }
+ }
+ //
+ if (add.fQuadrantQ2) {
+ if (fQuadrantQ2) fQuadrantQ2->Add(weight*(*(add.fQuadrantQ2)));
+ if (!fQuadrantQ2) {
+ fQuadrantQ2 = (TVectorD*)(add.fQuadrantQ2->Clone());
+ (*fQuadrantQ2)*=weight;
+ }
+ }
+ if (add.fQuadrantRQ2) {
+ if (fQuadrantRQ2) fQuadrantRQ2->Add(weight*(*(add.fQuadrantRQ2)));
+ if (!fQuadrantRQ2) {
+ fQuadrantRQ2 = (TVectorD*)(add.fQuadrantRQ2->Clone());
+ (*fQuadrantQ2)*=weight;
+ }
+ }
+ //
+ // Global alignment - use native ROOT representation
+ //
+ Double_t delta[3]={0};
+ if (add.fMatrixGlobal){
+ TGeoHMatrix matrixW=*(add.fMatrixGlobal);
+ TGeoHMatrix matrixScaled;
+ const Double_t *rotMatrix = matrixW.GetRotationMatrix();
+ const Double_t *transMatrix = matrixW.GetTranslation();
+ matrixScaled.RotateZ(-rotMatrix[1]*TMath::RadToDeg()*weight);
+ matrixScaled.RotateY(rotMatrix[2]*TMath::RadToDeg()*weight);
+ matrixScaled.RotateX(-rotMatrix[5]*TMath::RadToDeg()*weight);
+ for (Int_t i=0; i<3; i++) delta[i]=weight*transMatrix[i];
+ matrixScaled.SetTranslation(delta);
+ // (matrixScaled*matrixW).Print(); in case weight -1 should be unit matrix
+ //
+ if (!fMatrixGlobal) {
+ fMatrixGlobal = new TGeoHMatrix(matrixScaled);
+ }else{
+ ((TGeoHMatrix*)fMatrixGlobal)->Multiply(&matrixScaled);
+ }
+ }
+ if (add.fMatrixGlobalDelta){
+ TGeoHMatrix matrixW=*(add.fMatrixGlobalDelta);
+ TGeoHMatrix matrixScaled;
+ const Double_t *rotMatrix = matrixW.GetRotationMatrix();
+ const Double_t *transMatrix = matrixW.GetTranslation();
+ matrixScaled.RotateZ(-rotMatrix[1]*TMath::RadToDeg()*weight);
+ matrixScaled.RotateY(rotMatrix[2]*TMath::RadToDeg()*weight);
+ matrixScaled.RotateX(-rotMatrix[5]*TMath::RadToDeg()*weight);
+ for (Int_t i=0; i<3; i++) delta[i]=weight*transMatrix[i];
+ matrixScaled.SetTranslation(delta);
+ // (matrixScaled*matrixW).Print(); in case weight -1 should be unit matrix
+ //
+ if (!fMatrixGlobalDelta) {
+ fMatrixGlobalDelta = new TGeoHMatrix(matrixScaled);
+ }else{
+ ((TGeoHMatrix*)fMatrixGlobalDelta)->Multiply(&matrixScaled);
+ }
+ }
+ if (add.fArraySector){
+ if (!fArraySector) {
+ fArraySector = new TObjArray(72);
+ for (Int_t isec=0; isec<72; isec++) fArraySector->AddAt(new TGeoHMatrix,isec);
+ }
+ for (Int_t isec=0; isec<72; isec++){
+ TGeoHMatrix *mat0= (TGeoHMatrix*)fArraySector->At(isec);
+ TGeoHMatrix *mat1= (TGeoHMatrix*)add.fArraySector->At(isec);
+ if (mat0&&mat1){
+ TGeoHMatrix matrixW=*(mat1);
+ TGeoHMatrix matrixScaled;
+ const Double_t *rotMatrix = matrixW.GetRotationMatrix();
+ const Double_t *transMatrix = matrixW.GetTranslation();
+ matrixScaled.RotateZ(-rotMatrix[1]*TMath::RadToDeg()*weight);
+ matrixScaled.RotateY(rotMatrix[2]*TMath::RadToDeg()*weight);
+ matrixScaled.RotateX(-rotMatrix[5]*TMath::RadToDeg()*weight);
+ for (Int_t i=0; i<3; i++) delta[i]=weight*transMatrix[i];
+ matrixScaled.SetTranslation(delta);
+ mat0->Multiply(&matrixScaled);
+ }
+ }
+ }
+ //
+ return kTRUE;
+}
+
+
+
+
void AliTPCCalibGlobalMisalignment::SetQuadranAlign(const TVectorD *quadrantQ0, const TVectorD *quadrantRQ0, const TVectorD *quadrantQ1,const TVectorD *quadrantRQ1, const TVectorD *quadrantQ2, const TVectorD *quadrantRQ2){
//
// Set quadrant alignment