hit = new (a[fNhits]) AliFMDHit(fIshunt, track, detector, ring, sector,
strip, x, y, z, px, py, pz, edep, pdg, t,
l, stop);
+ // gMC->AddTrackReference(track, 12);
fNhits++;
//Reference track
Short_t(digits[8]), // ADC Count4
UShort_t(digits[9]), // N particles
UShort_t(digits[10])); // N primaries
-
}
//____________________________________________________________________
void
-AliFMD::AddSDigitByFields(UShort_t detector,
- Char_t ring,
- UShort_t sector,
- UShort_t strip,
- Float_t edep,
- UShort_t count1,
- Short_t count2,
- Short_t count3,
- Short_t count4,
- UShort_t ntot,
- UShort_t nprim)
+AliFMD::AddSDigitByFields(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t edep,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3,
+ Short_t count4,
+ UShort_t ntot,
+ UShort_t nprim,
+ const TArrayI& refs)
{
// add a summable digit
//
new (a[fNsdigits++])
AliFMDSDigit(detector, ring, sector, strip, edep,
- count1, count2, count3, count4, ntot, nprim);
+ count1, count2, count3, count4, ntot, nprim, refs);
}
//____________________________________________________________________
#ifndef ALIDETECTOR_H
# include <AliDetector.h>
#endif
+#ifndef ROOT_TArrayI
+# include <TArrayI.h>
+#endif
class TBranch;
class TClonesArray;
class TBrowser;
class TMarker3DBox;
+class TArrayI;
class AliDigitizer;
class AliFMDHit;
@param count1 ADC count (a 10-bit word)
@param count2 ADC count (a 10-bit word), or -1 if not used
@param count3 ADC count (a 10-bit word), or -1 if not used */
- virtual void AddSDigitByFields(UShort_t detector=0,
- Char_t ring='\0',
- UShort_t sector=0,
- UShort_t strip=0,
- Float_t edep=0,
- UShort_t count1=0,
- Short_t count2=-1,
- Short_t count3=-1,
- Short_t count4=-1,
- UShort_t ntot=0,
- UShort_t nprim=0);
+ virtual void AddSDigitByFields(UShort_t detector=0,
+ Char_t ring='\0',
+ UShort_t sector=0,
+ UShort_t strip=0,
+ Float_t edep=0,
+ UShort_t count1=0,
+ Short_t count2=-1,
+ Short_t count3=-1,
+ Short_t count4=-1,
+ UShort_t ntot=0,
+ UShort_t nprim=0,
+ const TArrayI& refs=TArrayI());
/** @}*/
/** @{ */
// Constructor
// SetInnerZ(83.4);
// SetOuterZ(75.2);
- Double_t off = 0.414256-0.1963; // 2.35
+ // Double_t off = 0.414256-0.1963; // 2.35
+ Double_t off = 0.414256-0.1963+.27; // 2.35
+ if (off < 0) off = 0;
if (off != 0)
AliWarning(Form("Z position of FMD2 rings may be wrong by %fcm!", off));
SetInnerZ(83.4+off);
AliFMDMap::kMaxRings,
AliFMDMap::kMaxSectors,
AliFMDMap::kMaxStrips),
- fShapingTime(6)
+ fShapingTime(6),
+ fStoreTrackRefs(kFALSE)
{
AliFMDDebug(1, ("Constructed"));
// Default ctor - don't use it
AliFMDMap::kMaxRings,
AliFMDMap::kMaxSectors,
AliFMDMap::kMaxStrips),
- fShapingTime(6)
+ fShapingTime(6),
+ fStoreTrackRefs(kFALSE)
{
// Normal CTOR
AliFMDDebug(1, ("Constructed"));
AliFMDMap::kMaxRings,
AliFMDMap::kMaxSectors,
AliFMDMap::kMaxStrips),
- fShapingTime(6)
+ fShapingTime(6),
+ fStoreTrackRefs(kFALSE)
{
// Normal CTOR
AliFMDDebug(1, (" Constructed"));
UShort_t sector,
UShort_t strip,
Float_t edep,
- Bool_t isPrimary)
+ Bool_t isPrimary,
+ Int_t trackno)
{
// Add edep contribution from (detector,ring,sector,strip) to cache
AliFMDParameters* param = AliFMDParameters::Instance();
// continue;
// }
+ AliFMDEdepHitPair& entry = fEdep(detector, ring, sector, strip);
+
// Give warning in case of double sdigit
- if (fEdep(detector, ring, sector, strip).fEdep != 0)
- AliFMDDebug(5, ("Double digit in %d%c(%d,%d)",
+ if (entry.fEdep != 0)
+ AliFMDDebug(5, ("Double digit in FMD%d%c[%2d,%3d]",
detector, ring, sector, strip));
// Sum energy deposition
- fEdep(detector, ring, sector, strip).fEdep += edep;
- fEdep(detector, ring, sector, strip).fN += 1;
- if (isPrimary)
- fEdep(detector, ring, sector, strip).fNPrim += 1;
+ entry.fEdep += edep;
+ entry.fN += 1;
+ if (isPrimary) entry.fNPrim += 1;
+ if (fStoreTrackRefs) {
+ entry.fLabels.Set(entry.fN);
+ entry.fLabels[entry.fN-1] = trackno;
+ }
AliFMDDebug(15, ("Adding contribution %f to FMD%d%c[%2d,%3d] (%f)",
- edep, detector, ring, sector, strip,
- fEdep(detector, ring, sector, strip).fEdep));
+ edep, detector, ring, sector, strip,
+ entry.fEdep));
}
// VA1_ALICE channel.
if (strip % 128 == 0) last = 0;
- Float_t edep = fEdep(detector, ring, sector, strip).fEdep;
- UShort_t ntot = fEdep(detector, ring, sector, strip).fN;
- UShort_t nprim = fEdep(detector, ring, sector, strip).fNPrim;
+ const AliFMDEdepHitPair& entry = fEdep(detector,ring,sector,strip);
+ Float_t edep = entry.fEdep;
+ UShort_t ntot = entry.fN;
+ UShort_t nprim = entry.fNPrim;
+ const TArrayI& labels = entry.fLabels;
if (edep > 0)
AliFMDDebug(15, ("Edep = %f for FMD%d%c[%2d,%3d]",
edep, detector, ring, sector, strip));
AddDigit(detector, ring, sector, strip, edep,
UShort_t(counts[0]), Short_t(counts[1]),
Short_t(counts[2]), Short_t(counts[3]),
- ntot, nprim);
+ ntot, nprim, labels);
AliFMDDebug(15, (" Adding digit in FMD%d%c[%2d,%3d]=%d",
detector,ring,sector,strip,counts[0]));
#if 0
//____________________________________________________________________
void
-AliFMDBaseDigitizer::AddDigit(UShort_t detector,
- Char_t ring,
- UShort_t sector,
- UShort_t strip,
- Float_t /* edep */,
- UShort_t count1,
- Short_t count2,
- Short_t count3,
- Short_t count4,
- UShort_t /* ntot */,
- UShort_t /* nprim */) const
+AliFMDBaseDigitizer::AddDigit(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t /* edep */,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3,
+ Short_t count4,
+ UShort_t /* ntot */,
+ UShort_t /* nprim */,
+ const TArrayI& /* refs */) const
{
// Add a digit or summable digit
void SetShapingTime(Float_t B=10) { fShapingTime = B; }
/** @return Get the shaping time */
Float_t GetShapingTime() const { return fShapingTime; }
+
+ void SetStoreTrackRefs(Bool_t store=kTRUE) { fStoreTrackRefs = store; }
+ Bool_t IsStoreTrackRefs() const { return fStoreTrackRefs; }
+
protected:
/** For the stored energy contributions in the cache, convert the
energy signal to ADC counts, and store the created digit in
UShort_t sector,
UShort_t strip,
Float_t edep,
- Bool_t isPrimary);
+ Bool_t isPrimary,
+ Int_t trackno);
/** Add a digit to output */
- virtual void AddDigit(UShort_t detector,
- Char_t ring,
- UShort_t sector,
- UShort_t strip,
- Float_t edep,
- UShort_t count1,
- Short_t count2,
- Short_t count3,
- Short_t count4,
- UShort_t ntot,
- UShort_t nprim) const;
+ virtual void AddDigit(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t edep,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3,
+ Short_t count4,
+ UShort_t ntot,
+ UShort_t nprim,
+ const TArrayI& refs) const;
/** Make the output tree using the passed loader
@param loader
@return The generated tree. */
@param loader The loader */
virtual void StoreDigits(AliLoader* loader);
- AliFMD* fFMD;
- AliRunLoader* fRunLoader; //! Run loader
- AliFMDEdepMap fEdep; // Cache of Energy from hits
- Float_t fShapingTime; // Shaping profile parameter
+ AliFMD* fFMD; // Detector object
+ AliRunLoader* fRunLoader; //! Run loader
+ AliFMDEdepMap fEdep; // Cache of Energy from hits
+ Float_t fShapingTime; // Shaping profile parameter
+ Bool_t fStoreTrackRefs; // Wether to store track references
/** Copy CTOR
@param o object to copy from */
fFMD(o.fFMD),
fRunLoader(0),
fEdep(o.fEdep),
- fShapingTime(o.fShapingTime)
+ fShapingTime(o.fShapingTime),
+ fStoreTrackRefs(o.fStoreTrackRefs)
{}
/** Assignment operator
@return Reference to this object */
AliFMDBaseDigitizer& operator=(const AliFMDBaseDigitizer& o)
{
AliDigitizer::operator=(o);
- fRunLoader = o.fRunLoader;
- fEdep = o.fEdep;
- fShapingTime = o.fShapingTime;
+ fRunLoader = o.fRunLoader;
+ fEdep = o.fEdep;
+ fShapingTime = o.fShapingTime;
+ fStoreTrackRefs = o.fStoreTrackRefs;
return *this;
}
ClassDef(AliFMDBaseDigitizer,2) // Base class for FMD digitizers
if (fOuter && !fOuterTransforms)
fOuterTransforms = new TObjArray(fOuter->GetNModules());
+ // Loop over bottom/top
+ for (size_t ihalf = 0; ihalf < 2; ihalf++) {
+ char half = (ihalf == 0 ? 'T' : 'B');
+ TString path(Form(HALF_FORMAT, fId, half));
+ TGeoPNEntry* entry = gGeoManager->GetAlignableEntry(path.Data());
+ if (!entry) {
+ AliError(Form("Alignable entry for half-detector \"%s\" not found!",
+ path.Data()));
+ continue;
+ }
+ TGeoPhysicalNode* pn = entry->GetPhysicalNode();
+ if (!pn) {
+ AliWarning(Form("Making physical volume for \"%s\"", path.Data()));
+ pn = gGeoManager->MakeAlignablePN(entry);
+ if (!pn) {
+ AliError(Form("No physical node for \"%s\"", path.Data()));
+ continue;
+ }
+ }
+ }
+
// Loop over rings
for (size_t iring = 0; iring < 2; iring++) {
char ring = (iring == 0 ? 'I' : 'O');
fmdSDigit->Sector(),
fmdSDigit->Strip(),
fmdSDigit->Edep(),
- kTRUE);
+ kTRUE,
+ -1);
} // sdigit loop
} // event loop
#ifndef ROOT_Rtypes
# include <Rtypes.h>
#endif
+#ifndef ROOT_TArrayI
+# include <TArrayI.h>
+#endif
+
//____________________________________________________________________
/** @brief Cache of Energy deposited, hit information per strip.
Contains a pair of energy deposited @c fEdep and
class AliFMDEdepHitPair
{
public:
- Float_t fEdep; // summed energy deposition
- UShort_t fN; // Number of hits
- UShort_t fNPrim; // Number of primaries;
+ Float_t fEdep; // summed energy deposition
+ UShort_t fN; // Number of hits
+ UShort_t fNPrim; // Number of primaries;
+ TArrayI fLabels; // Track labels.
/** CTOR */
- AliFMDEdepHitPair() : fEdep(0), fN(0), fNPrim(0) {}
+ AliFMDEdepHitPair() : fEdep(0), fN(0), fNPrim(0), fLabels(0) {}
/** DTOR */
virtual ~AliFMDEdepHitPair() {}
/** Assignment operator
@return Reference to this object */
AliFMDEdepHitPair& operator=(const AliFMDEdepHitPair& o)
{
- fEdep = o.fEdep;
- fN = o.fN;
- fNPrim = o.fNPrim;
+ fEdep = o.fEdep;
+ fN = o.fN;
+ fNPrim = o.fNPrim;
+ fLabels = o.fLabels;
return *this;
}
/** Copy CTOR
@param o Object to copy from */
AliFMDEdepHitPair(const AliFMDEdepHitPair& o)
- : fEdep(o.fEdep), fN(o.fN), fNPrim(o.fNPrim)
+ : fEdep(o.fEdep), fN(o.fN), fNPrim(o.fNPrim), fLabels(o.fLabels)
{}
- ClassDef(AliFMDEdepHitPair, 2)
+ ClassDef(AliFMDEdepHitPair, 3)
};
#endif
fData[i].fEdep = val.fEdep;
fData[i].fN = val.fN;
fData[i].fNPrim = val.fNPrim;
+ fData[i].fLabels.Set(0);
};
}
Double_t framelr = 32.01; // fmd2->GetOuterHoneyHighR()+0.5;
Double_t framehr = 33.611; // fmd2->GetOuterHoneyHighR()+1.8;
Double_t framel = 14.8; // framehz - framelz;
- Double_t backth = 0.3;
+ // Double_t backth = 0.3;
+ Double_t backth = 0.03;
Double_t framelz = -(2.38
- r->GetModuleDepth()
- r->GetModuleSpacing() / 2);
"FMD Hit->Digit digitizer" :
"FMD Hit->SDigit digitizer")),
fOutput(output),
+ fHoldTime(2e-6),
fStack(0)
{
fFMD = fmd;
// Get the hit number `hit'
AliFMDHit* fmdHit =
static_cast<AliFMDHit*>(fmdHits->UncheckedAt(hit));
+
+ // Ignore hits that arrive too late
+ if (fmdHit->Time() > fHoldTime) continue;
+
// Check if this is a primary particle
Bool_t isPrimary = kTRUE;
+ Int_t trackno = -1;
if (fStack) {
- Int_t trackno = fmdHit->Track();
+ trackno = fmdHit->Track();
AliFMDDebug(10, ("Will get track # %d/%d from entry # %d",
trackno, fStack->GetNtrack(), track));
if (fStack->GetNtrack() < trackno) {
trackno, fStack->GetNtrack()));
continue;
}
-
+#if 1
+ isPrimary = fStack->IsPhysicalPrimary(trackno);
+#else // This is our hand-crafted code. We use the ALICE definition
TParticle* part = fStack->Particle(trackno);
isPrimary = part->IsPrimary();
if (!isPrimary) {
(mother ? mother->GetStatusCode() : -1),
(isPrimary ? "primary" : "secondary")));
}
+#endif
}
// Extract parameters
fmdHit->Sector(),
fmdHit->Strip(),
fmdHit->Edep(),
- isPrimary);
+ isPrimary,
+ trackno);
} // hit loop
} // track loop
AliFMDDebug(5, ("Size of cache: %d bytes, read %d bytes",
//____________________________________________________________________
void
-AliFMDHitDigitizer::AddDigit(UShort_t detector,
- Char_t ring,
- UShort_t sector,
- UShort_t strip,
- Float_t edep,
- UShort_t count1,
- Short_t count2,
- Short_t count3,
- Short_t count4,
- UShort_t ntotal,
- UShort_t nprim) const
+AliFMDHitDigitizer::AddDigit(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t edep,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3,
+ Short_t count4,
+ UShort_t ntotal,
+ UShort_t nprim,
+ const TArrayI& refs) const
{
// Add a digit or summable digit
if (fOutput == kDigits) {
AliFMDBaseDigitizer::AddDigit(detector, ring, sector, strip, 0,
- count1, count2, count3, count4, 0, 0);
+ count1, count2, count3, count4, 0, 0, refs);
return;
}
if (edep <= 0) {
count1, count2, count3, count4, nprim, ntotal));
fFMD->AddSDigitByFields(detector, ring, sector, strip, edep,
count1, count2, count3, count4,
- ntotal, nprim);
+ ntotal, nprim, refs);
}
//____________________________________________________________________
AliFMDHitDigitizer()
: AliFMDBaseDigitizer(),
fOutput(kDigits),
+ fHoldTime(2e-6),
fStack(0)
{}
/** CTOR
virtual ~AliFMDHitDigitizer() {}
/** Run over the input events (retrieved via run loader) */
void Exec(Option_t* option="");
+ /**
+ * Set the end of integration
+ *
+ * @param holdT Time when integration ends (nominally @f$
+ * 2\mu{}s@f$)
+ */
+ void SetHoldTime(Double_t holdT=2e-6) { fHoldTime = holdT; }
+ Double_t GetHoldTime() const { return fHoldTime; }
protected:
/** Copy constructor
@param o Object to copy from */
AliFMDHitDigitizer(const AliFMDHitDigitizer& o)
: AliFMDBaseDigitizer(o),
fOutput(o.fOutput),
+ fHoldTime(2e-6),
fStack(o.fStack)
{}
/** Assignment operator
AliFMDHitDigitizer& operator=(const AliFMDHitDigitizer& o)
{
AliFMDBaseDigitizer::operator=(o);
+ fHoldTime = o.fHoldTime;
fOutput = o.fOutput;
+ fStack = o.fStack;
return *this;
}
/** Make the output tree using the passed loader
@param count2 ADC count 2 (-1 if not used)
@param count3 ADC count 3 (-1 if not used)
@param count4 ADC count 4 (-1 if not used) */
- void AddDigit(UShort_t detector,
- Char_t ring,
- UShort_t sector,
- UShort_t strip,
- Float_t edep,
- UShort_t count1,
- Short_t count2,
- Short_t count3,
- Short_t count4,
- UShort_t ntot,
- UShort_t nprim) const;
+ void AddDigit(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t edep,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3,
+ Short_t count4,
+ UShort_t ntot,
+ UShort_t nprim,
+ const TArrayI& trackrefs) const;
/** Check that digit data is consistent
@param digit Digit
@param nhits Number of hits
Output_t fOutput; // Output mode
+ Double_t fHoldTime; // Stop of integration
AliStack* fStack; // Kinematics
ClassDef(AliFMDHitDigitizer,1) // Make Digits from Hits
fCount1(0),
fCount2(-1),
fCount3(-1),
- fCount4(-1)
+ fCount4(-1),
+ fLabels(0)
{
// cTOR
}
//____________________________________________________________________
-AliFMDSDigit::AliFMDSDigit(UShort_t detector,
- Char_t ring,
- UShort_t sector,
- UShort_t strip,
- Float_t edep,
- UShort_t count1,
- Short_t count2,
- Short_t count3,
- Short_t count4,
- UShort_t npart,
- UShort_t nprim)
+AliFMDSDigit::AliFMDSDigit(UShort_t detector,
+ Char_t ring,
+ UShort_t sector,
+ UShort_t strip,
+ Float_t edep,
+ UShort_t count1,
+ Short_t count2,
+ Short_t count3,
+ Short_t count4,
+ UShort_t npart,
+ UShort_t nprim,
+ const TArrayI& refs)
: AliFMDBaseDigit(detector, ring, sector, strip),
fEdep(edep),
fCount1(count1),
fCount3(count3),
fCount4(count4),
fNParticles(npart),
- fNPrimaries(nprim)
+ fNPrimaries(nprim),
+ fLabels(refs)
{
//
// Creates a real data digit object
//____________________________________________________________________
void
-AliFMDSDigit::Print(Option_t* /* option*/) const
+AliFMDSDigit::Print(Option_t* option) const
{
// Print digit to standard out
AliFMDBaseDigit::Print();
- cout << "\t" << fEdep << " -> "
- << fCount1 << " (" << fCount2 << "," << fCount3 << ","
- << fCount4 << ") = " << Counts() << endl;
+ std::cout << "\t" << fEdep << " -> "
+ << fCount1 << " (" << fCount2 << "," << fCount3 << ","
+ << fCount4 << ") = " << Counts() << std::flush;
+ TString opt(option);
+ if (opt.Contains("p", TString::kIgnoreCase))
+ std::cout << " [" << fNPrimaries << "/" << fNParticles << "]"
+ << std::flush;
+ if (opt.Contains("l", TString::kIgnoreCase)) {
+ std::cout << " ";
+ for (Int_t i = 0; i < fLabels.fN; i++)
+ std::cout << (i == 0 ? "" : ",") << fLabels.fArray[i];
+ }
+ std::cout << std::endl;
}
//____________________________________________________________________
#ifndef ALIFMDBASEDIGIT_H
# include <AliFMDBaseDigit.h>
#endif
+#ifndef ROOT_TArrayI
+# include <TArrayI.h>
+#endif
+
//____________________________________________________________________
/** @class AliFMDSDigit AliFMDDigit.h <FMD/AliFMDDigit.h>
@brief class for summable digits
@param count ADC (first sample)
@param count2 ADC (second sample, or -1 if not used)
@param count3 ADC (third sample, or -1 if not used) */
- AliFMDSDigit(UShort_t detector,
- Char_t ring='\0',
- UShort_t sector=0,
- UShort_t strip=0,
- Float_t edep=0,
- UShort_t count=0,
- Short_t count2=-1,
- Short_t count3=-1,
- Short_t count4=-1,
- UShort_t npart=0,
- UShort_t nprim=0);
+ AliFMDSDigit(UShort_t detector,
+ Char_t ring='\0',
+ UShort_t sector=0,
+ UShort_t strip=0,
+ Float_t edep=0,
+ UShort_t count=0,
+ Short_t count2=-1,
+ Short_t count3=-1,
+ Short_t count4=-1,
+ UShort_t npart=0,
+ UShort_t nprim=0,
+ const TArrayI& refs=TArrayI());
/** DTOR */
virtual ~AliFMDSDigit() {}
/** @return ADC count (first sample) */
UShort_t NParticles() const { return fNParticles; }
/** @return Number of primary particles that hit this strip */
UShort_t NPrimaries() const { return fNPrimaries; }
-
+ /** @return the track labels */
+ const TArrayI& TrackLabels() const { return fLabels; }
/** Print info
@param opt Not used */
void Print(Option_t* opt="") const;
Short_t fCount4; // Digital signal (-1 if not used)
UShort_t fNParticles; // Total number of particles that hit this strip
UShort_t fNPrimaries; // Number of primary particles that his this strip
- ClassDef(AliFMDSDigit,3) // Summable FMD digit
+ TArrayI fLabels; // MC-truth track labels
+ ClassDef(AliFMDSDigit,4) // Summable FMD digit
};
inline UShort_t
--- /dev/null
+#include "AliFMDSurveyToAlignObjs.h"
+#include "AliSurveyPoint.h"
+#include <TGraph2DErrors.h>
+#include <TF2.h>
+#include <TVector3.h>
+#include <iostream>
+#include <iomanip>
+#include <TMath.h>
+#include <TRotation.h>
+#include <TGeoMatrix.h>
+#include <TGeoManager.h>
+#include <TGeoPhysicalNode.h>
+#include "AliFMDGeometry.h"
+
+//____________________________________________________________________
+Bool_t
+AliFMDSurveyToAlignObjs::GetFMD2Plane(Double_t* rot,
+ Double_t* trans)
+{
+
+ // The possile survey points
+ const char* names[] = { "FMD2_ITOP", "FMD2_OTOP",
+ "FMD2_IBOTM", "FMD2_OBOTM",
+ "FMD2_IBOT", "FMD2_OBOT",
+ 0 };
+ const char** name = names;
+ Int_t i = 0;
+ TGraph2DErrors g;
+
+ Double_t unit = 1.;
+ TString units(fSurveyObj->GetUnits());
+ if (units.CompareTo("mm", TString::kIgnoreCase) == 0) unit = .1;
+ else if (units.CompareTo("cm", TString::kIgnoreCase) == 0) unit = 1.;
+ else if (units.CompareTo("m", TString::kIgnoreCase) == 0) unit = 100.;
+
+ // Loop and fill graph
+ while (*name) {
+ TObject* obj = fSurveyPoints->FindObject(*name);
+ name++;
+ if (!obj) continue;
+
+ AliSurveyPoint* p = static_cast<AliSurveyPoint*>(obj);
+ Double_t x = unit * p->GetX();
+ Double_t y = unit * p->GetY();
+ Double_t z = unit * p->GetZ();
+ Double_t ex = unit * p->GetPrecisionX();
+ Double_t ey = unit * p->GetPrecisionY();
+ Double_t ez = unit * p->GetPrecisionZ();
+
+ g.SetPoint(i, x, y, z);
+ g.SetPointError(i, ex, ey, ez);
+ i++;
+ }
+
+ // Check that we have enough points
+ if (g.GetN() < 4) {
+ Error("GetFMD2Plane", "Only got %d survey points - no good for FMD2 plane",
+ g.GetN());
+ return kFALSE;
+ }
+
+ // Next, declare fitting function and fit to graph.
+ // Fit to the plane equation:
+ //
+ // ax + by + cz + d = 0
+ //
+ // or
+ //
+ // z = - ax/c - by/c - d/c
+ //
+ TF2 f("fmd2Plane", "-[0]*x-[1]*y-[2]",
+ g.GetXmin(), g.GetXmax(), g.GetYmin(), g.GetYmax());
+ g.Fit(&f, "Q");
+
+ // Now, extract the normal and offset
+ TVector3 nv(f.GetParameter(0), f.GetParameter(1), 1);
+ TVector3 n(nv.Unit());
+ Double_t p = -f.GetParameter(2);
+
+ // Create two vectors spanning the plane
+ TVector3 a(1, 0, f.Eval(1, 0)-p);
+ TVector3 b(0, -1, f.Eval(0, -1)-p);
+ TVector3 ua(a.Unit());
+ TVector3 ub(b.Unit());
+ Double_t angAb = ua.Angle(ub);
+ PrintVector("ua: ", ua);
+ PrintVector("ub: ", ub);
+ std::cout << "Angle: " << angAb * 180 / TMath::Pi() << std::endl;
+
+ for (size_t i = 0; i < 3; i++) {
+ rot[i * 3 + 0] = ua[i];
+ rot[i * 3 + 1] = ub[i];
+ rot[i * 3 + 2] = n[i];
+ }
+
+ // The intersection of the plane is given by (0, 0, -d/c)
+ trans[0] = 0;
+ trans[1] = 0;
+ trans[2] = p;
+
+ return kTRUE;
+}
+
+#define M(I,J) rot[(J-1) * 3 + (I-1)]
+//____________________________________________________________________
+Bool_t
+AliFMDSurveyToAlignObjs::DoFMD2()
+{
+ Double_t rot[9], trans[3];
+ if (!GetFMD2Plane(rot, trans)) return kFALSE;
+
+ PrintRotation("Rotation: ", rot);
+ PrintVector("Translation: ", trans);
+
+#if 0
+ Double_t theta = TMath::ATan2(M(3,1), M(3,2));
+ Double_t phi = TMath::ACos(M(3,3));
+ Double_t psi = -TMath::ATan2(M(1,3), M(2,3));
+
+ std::cout << " Theta=" << theta * 180 / TMath::Pi()
+ << " Phi=" << phi * 180 / TMath::Pi()
+ << " Psi=" << psi * 180 / TMath::Pi()
+ << std::endl;
+
+ TRotation r;
+ r.SetXEulerAngles(theta, phi, psi);
+ r.Print();
+
+ TGeoRotation* geoR = new TGeoRotation("FMD2_survey_rotation",
+ r.GetYTheta(),
+ r.GetYPhi(),
+ r.GetYPsi());
+ TGeoCombiTrans* geoM = new TGeoCombiTrans(trans[0], trans[1], trans[2], geoR);
+#else
+ TGeoHMatrix* geoM = new TGeoHMatrix;
+ geoM->SetRotation(rot);
+ geoM->SetTranslation(trans);
+#endif
+ geoM->Print();
+
+ const char* path = "/ALIC_1/F2MT_2/FMD2_support_0/FMD2_back_cover_2";
+ gGeoManager->cd(path);
+ TGeoMatrix* globalBack = gGeoManager->GetCurrentMatrix();
+ globalBack->Print();
+ PrintRotation("Back rotation:", globalBack->GetRotationMatrix());
+ PrintVector("Back translation:", globalBack->GetTranslation());
+
+ // TObjArray* pns = gGeoManager->GetListOfPhysicalNodes();
+ // TObject* oT = pns->FindObject("/ALIC_1/F2MT_2");
+ // TObject* oB = pns->FindObject("/ALIC_1/F2MB_2");
+ // if (!oT) {
+ // Warning("DoFMD2", Form("Physical node /ALIC_1/F2MT_2 not found"));
+ // return kFALSE;
+ // }
+ // if (!oB) {
+ // Warning("DoFMD2", Form("Physical node /ALIC_1/F2MB_2 not found"));
+ // return kFALSE;
+ // }
+ // TGeoPhysicalNode* top = static_cast<TGeoPhysicalNode*>(oT);
+ // TGeoPhysicalNode* bot = static_cast<TGeoPhysicalNode*>(oB);
+ TGeoHMatrix tDelta(globalBack->Inverse());
+ TGeoHMatrix bDelta(globalBack->Inverse());
+ PrintRotation("Back^-1 rotation:", tDelta.GetRotationMatrix());
+ PrintVector("Back^-1 translation:", tDelta.GetTranslation());
+
+ std::cout << "tDelta = 1? " << tDelta.IsIdentity() << std::endl;
+
+ tDelta.MultiplyLeft(geoM);
+ bDelta.MultiplyLeft(geoM);
+
+ PrintRotation("tDelta rotation:", tDelta.GetRotationMatrix());
+ PrintVector("tDelta translation:", tDelta.GetTranslation());
+ PrintRotation("bDelta rotation:", bDelta.GetRotationMatrix());
+ PrintVector("bDelta translation:", bDelta.GetTranslation());
+
+ return kTRUE;
+}
+
+//____________________________________________________________________
+void
+AliFMDSurveyToAlignObjs::Run()
+{
+ AliFMDGeometry* geom = AliFMDGeometry::Instance();
+ geom->Init();
+ geom->InitTransformations();
+
+ DoFMD2();
+}
+
+//____________________________________________________________________
+void
+AliFMDSurveyToAlignObjs::PrintVector(const char* text, const TVector3& v)
+{
+ Double_t va[] = { v.X(), v.Y(), v.Z() };
+ PrintVector(text, va);
+}
+//____________________________________________________________________
+void
+AliFMDSurveyToAlignObjs::PrintVector(const char* text, const Double_t* v)
+{
+ std::cout << text
+ << std::setw(15) << v[0]
+ << std::setw(15) << v[1]
+ << std::setw(15) << v[2]
+ << std::endl;
+}
+
+
+//____________________________________________________________________
+void
+AliFMDSurveyToAlignObjs::PrintRotation(const char* text, const Double_t* rot)
+{
+ std::cout << text << std::endl;
+ for (size_t i = 0; i < 3; i++) {
+ for (size_t j = 0; j < 3; j++)
+ std::cout << std::setw(15) << rot[i * 3 + j];
+ std::cout << std::endl;
+ }
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+#ifndef ALIFMDSURVEYTOALIGNOBJS_H
+#define ALIFMDSURVEYTOALIGNOBJS_H
+#include <AliSurveyToAlignObjs.h>
+
+// Forward decl
+class TVector3;
+
+
+class AliFMDSurveyToAlignObjs : public AliSurveyToAlignObjs
+{
+public:
+ AliFMDSurveyToAlignObjs() : AliSurveyToAlignObjs() {}
+ void Run();
+ Bool_t CreateAlignObjs() { return kTRUE; }
+protected:
+ Bool_t DoFMD2();
+ Bool_t GetFMD2Plane(Double_t* rot, Double_t* trans);
+
+ static void PrintVector(const char* text, const Double_t* v);
+ static void PrintVector(const char* text, const TVector3& v);
+ static void PrintRotation(const char* text, const Double_t* rot);
+
+
+ ClassDef(AliFMDSurveyToAlignObjs,0) // Convert FMD survey to alignments
+};
+
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+// mode: C++
+// End:
+//
+
#pragma link C++ class AliFMDPreprocessor+;
#pragma link C++ class AliFMDQAChecker+;
#pragma link C++ class AliFMDGeometryBuilder+;
+#pragma link C++ class AliFMDSurveyToAlignObjs+;
// #pragma link C++ class AliFMDAltroIO+;
// #pragma link C++ class AliFMDAltroReader+;
AliFMD3.cxx \
AliFMDPreprocessor.cxx \
AliFMDQAChecker.cxx \
- AliFMDGeometryBuilder.cxx
+ AliFMDGeometryBuilder.cxx \
+ AliFMDSurveyToAlignObjs.cxx
# AliFMDAltroIO.cxx
-HDRS = $(SRCS:.cxx=.h) \
- AliFMDStripIndex.h
+HDRS = $(SRCS:.cxx=.h)
DHDR := FMDbaseLinkDef.h
EINCLUDE := RAW
--- /dev/null
+void
+TestSurveyToAlignObjs()
+{
+ AliGeomManager::LoadGeometry("geometry.root");
+
+ AliFMDSurveyToAlignObjs convert;
+ convert.LoadSurveyFromLocalFile("$ALICE_ROOT/FMD/Survey_XXX_FMD.txt");
+ convert.Run();
+}
+