23#include <FairRootManager.h>
26#include <TGeoManager.h>
47 , fTriangleBinning(NULL)
52 SetNameTitle(Form(
"TrdSim2D%d", mod),
"Simulator for triangular read-out.");
75 printf(
"CbmTrdModuleSim2D::MakeDigi @ T[ns] = ev[%10.2f]+hit[%5.2f] ...\n", time, point->GetTime());
86 gGeoManager->MasterToLocal(gin, lin);
87 gGeoManager->MasterToLocal(gout, lout);
90 printf(
" ModPos : in[%7.4f %7.4f %7.4f] out[%7.4f %7.4f %7.4f]\n", lin[0], lin[1], lin[2], lout[0], lout[1],
94 Double_t ELossTR(0.), ELossdEdX(point->GetEnergyLoss());
100 ELossTR = gRandom->Uniform() > 0.89 ? 6.492 : 5.895;
106 printf(
"CbmTrdModuleSim2D::MakeDigi for %s ...\n", (
IsFeCalib() ?
"55Fe" :
"X-rays"));
107 if (ELossTR > 0) LOG(info) <<
" Ex " << ELossTR <<
" keV";
118 else if (gout[2] >= gin[2]) {
120 point->Momentum(mom);
127 Double_t trackLength(0.), txy(0.);
128 for (
Int_t i = 0; i < 3; i++) {
129 dd[i] = (lout[i] - lin[i]);
130 if (i == 2) txy = trackLength;
131 trackLength += dd[i] * dd[i];
133 if (trackLength > 0.) trackLength = TMath::Sqrt(trackLength);
135 LOG(warn) << GetName()
136 <<
"::MakeDigi: NULL track length for"
138 << std::setprecision(5) << ELossdEdX * 1e6 <<
") keV ";
141 if (txy > 0.) txy = TMath::Sqrt(txy);
143 LOG(warn) << GetName()
144 <<
"::MakeDigi: NULL xy track length projection for"
146 << std::setprecision(5) << ELossdEdX * 1e6 <<
") keV ";
150 Double_t dzdy = dd[2] / dd[1];
151 if (
VERBOSE) printf(
" dzdy[%f]\n", dzdy);
154 memcpy(ain, lin, 3 *
sizeof(Double_t));
157 memcpy(aout, lout, 3 *
sizeof(Double_t));
162 Int_t ncls = TMath::Nint(TMath::Abs(aout[1] - ain[1]) / dw + 1.);
164 printf(
" WireHit(s): %d\n", ncls);
165 printf(
" AnodePos : win[%7.4f / %7.4f] wout[%7.4f / %7.4f]\n", ain[1], lin[1], aout[1], lout[1]);
169 Int_t sgnx(1), sgny(1);
170 if (lout[0] < lin[0]) sgnx = -1;
171 if (lout[1] < lin[1]) sgny = -1;
172 Double_t dy[] = {TMath::Min((ain[1] + 0.5 * sgny * dw - lin[1]) * sgny, (lout[1] - lin[1]) * sgny),
173 TMath::Min((lout[1] - (aout[1] - 0.5 * sgny * dw)) * sgny, (lout[1] - lin[1]) * sgny)},
174 dxw(TMath::Abs(dd[0] * dw / dd[1])),
175 dx[] = {TMath::Abs(dy[0] * dd[0] / dd[1]), TMath::Abs(dy[1] * dd[0] / dd[1])};
177 Double_t DX(dx[0]), DY(dy[0]);
178 for (
Int_t ic(1); ic < ncls - 1; ic++) {
187 printf(
" DX[%7.4f] = dx0[%7.4f] + dx1[%7.4f] dwx[%7.4f] checkDX[%7.4f]\n"
188 " DY[%7.4f] = dy0[%7.4f] + dy1[%7.4f] dwy[%7.4f] checkDY[%7.4f]\n",
189 dd[0], dx[0], dx[1], dxw, sgnx * DX, dd[1], dy[0], dy[1], dw, sgny * DY);
192 Double_t
pos[3] = {ain[0], ain[1], ain[2]}, ldx(0.), ldy(0.), dxy(0.), e(0.),
193 tdrift, y0 = lin[1] - ain[1], z0 = lin[2];
194 for (
Int_t icl(0); icl < ncls; icl++) {
199 else if (icl == ncls - 1) {
208 dxy = ldx * ldx + ldy * ldy;
210 LOG(error) << GetName() <<
"::MakeDigi: NULL projected track length in cluster " << icl
211 <<
" for track length[cm] (" << std::setprecision(5) << ldx <<
", " << std::setprecision(2) << ldy
214 << std::setprecision(5) << ELossdEdX * 1e6 <<
") keV ";
217 dxy = TMath::Sqrt(dxy);
218 if (
VERBOSE) printf(
" %d ldx[%7.4f] ldy[%7.4f] xy[%7.4f] frac=%7.2f%%\n", icl, ldx, ldy, dxy, 1.e2 * dxy / txy);
220 Double_t dEdx(dxy / txy),
221 cELoss(ELossdEdX * dEdx);
225 printf(
" y0[%7.4f] z0[%7.4f] y1[%7.4f] z1[%7.4f]\n", y0, z0, y0 + ldy * sgny, z0 + dzdy * ldy * sgny);
228 z0 += dzdy * ldy * sgny;
229 pos[0] += 0.5 * ldx * sgnx;
230 if (
VERBOSE) printf(
" time_hit[ns]=%10.2f time_drift[ns]=%6.2f\n", time + point->GetTime(), tdrift);
235 pos[0] += 0.5 * ldx * sgnx;
242 if (TMath::Abs(ELossdEdX - e) > 1.e-3) {
243 LOG(warn) << GetName() <<
"::MakeDigi: dEdx partition to anode wires error : E[keV] = " << std::setprecision(5)
244 << ELossdEdX * 1e6 <<
" Sum(Ei)[keV]=" << std::setprecision(5) << e * 1e6;
249 Double_t lambda(0.3), diffx(0.1);
250 Double_t dist = gRandom->Exp(lambda);
251 if (
VERBOSE) printf(
" %d PE effect @ %7.4fcm trackLength=%7.4fcm\n", ncls, dist, trackLength);
252 if (dist > trackLength)
return kTRUE;
255 lin[0] += dd[0] * dist / trackLength;
256 lin[1] += dd[1] * dist / trackLength;
257 lin[2] += dd[2] * dist / trackLength;
259 memcpy(ain, lin, 3 *
sizeof(Double_t));
262 y0 = lin[1] - ain[1];
271 printf(
" yM[%7.4f] zM[%7.4f] -> yA[%7.4f] y0[%7.4f] "
272 "tDrift[ns]=%3d PE=%c EscPeak Edep=%5.3f [keV]\n",
273 lin[1], lin[2], ain[1], y0,
Int_t(tdrift), peShell, ELossTR);
279 printf(
" yM[%7.4f] zM[%7.4f] -> yA[%7.4f] y0[%7.4f] "
280 "tDrift[ns]=%3d PE=%c MainPeak Edep=%5.3f [keV]\n",
281 lin[1], lin[2], ain[1], y0,
Int_t(tdrift), peShell, ELossTR);
285 printf(
" yM[%7.4f] zM[%7.4f] -> yA[%7.4f] y0[%7.4f] tDrift[ns]=%3d "
287 lin[1], lin[2], ain[1], y0,
Int_t(tdrift), peShell);
310 printf(
" WirePlane : xy[%7.4f %7.4f] D[%7.4f] S[fC]=%7.4f "
312 point[0], point[1], DX, ELoss, toff);
315 point[0] += (gRandom->Rndm() - 0.5) * DX * 0.1;
317 Int_t sec(-1), col(-1), row(-1);
319 if (sec < 0 || col < 0 || row < 0) {
320 LOG(warn) <<
"CbmTrdModuleSim2D::ScanPadPlane: Hit to pad matching failed for [" << std::setprecision(5) << point[0]
321 <<
", " << std::setprecision(5) << point[1] <<
", " << std::setprecision(5) << point[2] <<
"].";
324 for (
Int_t is(0); is < sec; is++)
329 if (
VERBOSE) printf(
" PadPlane : col[%d] row[%d] x[%7.4f] y[%7.4f]\n", col, row, dx, dy);
334 LOG(warn) <<
"CbmTrdModuleSim2D::ScanPadPlane: Hit outside integration limits [" << std::setprecision(5) << dx
335 <<
", " << std::setprecision(5) << dy <<
"].";
346 Double_t array[nc][nr][2] = {{{0.}}}, prf(0.);
347 Int_t colOff, rowOff, up ;
358 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
359 printf(
"CbmTrdModuleSim2D::ScanPadPlane: Bin outside mapped array : "
366 if (up) array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
368 array[colOff][rowOff][0] += 0.5 * prf;
369 array[colOff][rowOff][1] += 0.5 * prf;
382 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
383 printf(
"CbmTrdModuleSim2D::ScanPadPlaneTriangleAB: Bin outside mapped "
384 "array : col[%d] row[%d]\n",
390 if (up) array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
392 array[colOff][rowOff][0] += 0.5 * prf;
393 array[colOff][rowOff][1] += 0.5 * prf;
413 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
414 printf(
"CbmTrdModuleSim2D::ScanPadPlane: Bin outside mapped array : "
421 if (up) array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
423 array[colOff][rowOff][0] += 0.5 * prf;
424 array[colOff][rowOff][1] += 0.5 * prf;
436 if (colOff < 0 || colOff >= nc || rowOff < 0 || rowOff >= nr) {
437 printf(
"CbmTrdModuleSim2D::ScanPadPlane: Bin outside mapped array : "
444 if (up) array[colOff][rowOff][(up > 0 ? 0 : 1)] += prf;
446 array[colOff][rowOff][0] += 0.5 * prf;
447 array[colOff][rowOff][1] += 0.5 * prf;
459 for (
Int_t ic(0); ic < nc; ic++)
460 printf(
"%7d[u/d] ", ic);
462 for (
Int_t ir(nr); ir--;) {
463 printf(
" r[%d] ", ir);
464 for (
Int_t ic(0); ic < nc; ic++)
465 printf(
"%6.4f/%6.4f ", 1.e2 * array[ic][ir][0], 1.e2 * array[ic][ir][1]);
475 Double_t Emeasure(0.);
476 for (
Int_t ir(nr); ir--;) {
477 for (
Int_t ic(nc); (--ic) >= 0;) {
478 for (
Int_t iup(0); iup < 2; iup++) {
481 Emeasure += array[ic][ir][iup];
488 if (ic < nc - 1) array[ic + 1][ir][0] += array[ic][ir][1];
489 array[ic][ir][1] += array[ic][ir][0];
493 printf(
" Sth[fC]=%6.4f Sdigi[fC]=%6.4f\n", ELoss, Emeasure);
495 for (
Int_t ic(0); ic < nc; ic++)
496 printf(
"%7d[T/R] ", ic);
498 for (
Int_t ir(nr); ir--;) {
499 printf(
" r[%d] ", ir);
500 for (
Int_t ic(0); ic < nc; ic++)
501 printf(
"%6.2f/%6.2f ", array[ic][ir][0], array[ic][ir][1]);
507 for (
Int_t ir(0); ir < nr; ir++) {
508 for (
Int_t ic(0); ic < nc; ic++) {
518 Double_t dch[2] = {0.};
520 for (
Int_t iup(0); iup < 2; iup++) {
521 if (array[ic][ir][iup] < 0.1)
continue;
522 dch[iup] = TMath::Nint(array[ic][ir][iup] * 10.);
531 AddDigi(address, &dch[0], toff);
547 LOG(warn) << GetName() <<
"::AddDigi: Failed to retrieve calibration for FASP channels allocated to pad " << pad;
551 if (!daqFaspChT) charge[0] = 0;
552 else if (daqFaspChT->IsMasked())
556 if (!daqFaspChR) charge[1] = 0;
564 digi =
new CbmTrdDigi(pad, charge[0], charge[1], uint64_t(time));
572 std::map<Int_t, std::vector<pair<CbmTrdDigi*, CbmMatch*>>>::iterator it =
fBuffer.find(pad);
577 for (std::vector<pair<CbmTrdDigi*, CbmMatch*>>::iterator itv =
fBuffer[pad].begin(); itv !=
fBuffer[pad].end();
580 if (sdigi->
GetTime() <= digi->GetTime())
continue;
581 fBuffer[pad].insert(itv, make_pair(digi, digiMatch));
587 fBuffer[pad].push_back(make_pair(digi, digiMatch));
588 if (
VERBOSE) cout <<
" => Save(B) " << digi->ToString();
592 if (
VERBOSE) cout <<
" => Add " << digi->ToString();
593 fBuffer[pad].push_back(make_pair(digi, digiMatch));
612 LOG(warn) << GetName() <<
"::FlushBuffer: Module operated with SPADIC. Development in progress.";
616 FairRootManager* ioman = FairRootManager::Instance();
622 if (!time) closeTS =
true;
627 if (time > 0 && !
fFASP->
Go(time) && !closeTS)
return 0;
632 printf(
"CbmTrdModuleSim2D::FlushBuffer(%llu) FASP start[%llu] end[%llu] "
637 cout <<
"\nPHYS DIGITS : \n";
640 Int_t asicId, asicOld(-1);
647 Int_t padAddress(0), ndigi(0);
648 std::map<Int_t, std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>>::iterator it =
fBuffer.begin();
649 for (; it !=
fBuffer.end(); it++) {
650 padAddress = it->first;
651 ndigi =
fBuffer[padAddress].size();
661 int chId[] = {-1, -1},
662 localAddress[] = {2 * padAddress, 2 * padAddress + 1},
666 if (faspIdOnMod[0] < 0 && faspIdOnMod[1] < 0) {
667 LOG(debug) << GetName() <<
"::FlushBuffer: FASP Calibration for pad " << padAddress <<
" at r/c=" << row <<
"/"
668 << col <<
" in module " <<
fModAddress <<
" missing.";
670 for (
auto iv =
fBuffer[padAddress].begin(); iv !=
fBuffer[padAddress].end(); iv++)
675 for (
int ifasp(0); ifasp < 2; ifasp++) {
676 asicId = faspIdOnMod[ifasp];
683 if (asicId != asicOld) {
686 LOG(debug) << GetName() <<
"::FlushBuffer: Found FASP " << asicId % 1000 <<
" for module " <<
fModAddress
687 <<
" local " << localAddress[ifasp];
692 chFasp[ifasp] = fasp->
GetChannel(chId[ifasp]);
700 cout <<
"\nFEE DIGITS : \n";
702 cout <<
"\nRAW DIGITS : \n";
706 Int_t n(0), nDigiLeft(0);
707 double timeMin(-1), timeMax(0),
711 padAddress = it->first;
718 Int_t col(-1), row(-1), srow, sec;
719 auto iv =
fBuffer[padAddress].begin();
720 while (iv !=
fBuffer[padAddress].end()) {
723 if (digi->
GetTime() < newStartTime) newStartTime = digi->
GetTime();
726 iv =
fBuffer[padAddress].erase(iv);
735 digiMatch->
AddLink(iv->second->GetLink(0));
738 iv =
fBuffer[padAddress].erase(iv);
746 printf(
"CbmTrdModuleSim2D::FlushBuffer : request ly[%d] mod[%d] "
747 "sec[%d] srow[%d] col[%d]\n",
751 if (timeMin < 0 || digi->GetTime() < timeMin) timeMin = digi->
GetTime();
755 digiMatch = iv->second;
759 double t, r = digi->
GetCharge(t, dt), noise[2];
760 gRandom->RndmArray(2, noise);
767 iv =
fBuffer[padAddress].erase(iv);
771 nDigiLeft +=
fBuffer[padAddress].size();
779 printf(
"CbmTrdModuleSim2D::FlushBuffer : write %d digis in [%d - "
780 "%d]ns. Digits still in buffer %d\n",
781 n, TMath::Nint(timeMin), TMath::Nint(timeMax), nDigiLeft);
801 for (std::map<
Int_t, std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>>::const_iterator it =
fBuffer.begin();
803 if (!it->second.size())
continue;
804 if (
VERBOSE > 1) printf(
"address[%10d] n[%2d]\n", it->first, (
Int_t) it->second.size());
805 for (std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::const_iterator iv = it->second.cbegin();
806 iv != it->second.cend(); iv++) {
807 cout <<
"\t" << (iv->first->IsFlagged(0) ?
'P' :
'D') <<
"[" << iv->first <<
"] " << iv->first->ToString();
808 if (
VERBOSE > 2) cout <<
"\t" << iv->second->ToString();
820 LOG(warn) << GetName() <<
"::SetAsicPar : The list for module " <<
fModAddress <<
" already initialized.";
ClassImp(CbmConverterManager)
Helper class to convert unique channel ID back and forth.
TRD digitizer. Updated 24/04/2013 by Andrey Lebedev andrey.lebedev@gsi.de Updated 4/06/2018 by Alex B...
static constexpr size_t size()
void SendData(Double_t time, Digi *digi, CbmMatch *match=nullptr)
Send a digi and the corresponding match object to the DAQ.
void AddLink(const CbmLink &newLink)
virtual std::string ToString() const
Return string representation of the object.
Bookkeeping of time-slice content.
double GetEndTime() const
static uint32_t GetModuleId(uint32_t address)
Return module ID from address.
std::string ToString() const
String representation of a TRD digi. Account for digi type and specific information.
bool IsFlagged(const int32_t iflag) const
Query flag status (generic)
bool IsMasked() const
Query digi mask (FASP only)
double GetTime() const
Getter for physical time [ns]. Accounts for clock representation of each ASIC. In SPADIC case physica...
double GetCharge() const
Common purpose charge getter.
void SetCharge(float c)
Charge setter for SPADIC ASIC.
static void SetNeighbourTrigger(Bool_t nb=kTRUE)
Set FASP trigger mode.
void SetProcTime(ULong64_t t=0)
Set limit in time for processing digis.
static void SetLGminLength(Int_t nclk)
Set linear-gate minimum length.
virtual void InitChannel(int id, const CbmTrdParFaspChannel *par, int asicId=-1, int chId=-1)
[Re]Initialize one of the two FASP channels
virtual Bool_t Go(ULong64_t time)
Check if there is enough time elapsed from fStartTime to run simulator.
virtual void Clear(Option_t *opt="")
Finalize currently stored data.
virtual void PhysToRaw(std::vector< std::pair< CbmTrdDigi *, CbmMatch * > > *digi)
Convert physics information in digi to the raw format.
virtual ULong64_t GetStartTime() const
void SetStartTime(ULong64_t t)
Set buffer time offset [ns].
virtual ULong64_t GetEndTime() const
Char_t fLayerId
layer identifier
const CbmTrdParModDigi * fDigiPar
read-out description of module
virtual Int_t GetPadAddress(Int_t r, Int_t c) const
Addressing read-out pads on module based on (row,col)
virtual const Char_t * GetPath() const
UShort_t fModAddress
unique identifier for current module
const CbmTrdParModGas * fChmbPar
detection description (HV, drift) of module
CbmTrdParModAsic * fAsicPar
the set of ASIC operating on the module (owned)
virtual Int_t GetPadRowCol(Int_t address, Int_t &c) const
Addressing read-out pads based on module address.
Simulation module implementation for TRD-2D physics and FEE.
Bool_t ScanPadPlane(Double_t *point, Double_t dx, Double_t E, Double_t tdrift)
Build digits for the triangular pad geometry.
void SetAsicPar(CbmTrdParModAsic *p=NULL)
Int_t FlushBuffer(ULong64_t time=0)
Flush local buffer of digits which can no longer interact with current event.
CbmTimeSlice * fTimeSlice
link to CBM time slice
Bool_t MakeDigi(CbmTrdPoint *p, Double_t time, Bool_t TR)
Steer building of digits for triangular pad geometry.
CbmTrdFASP * fFASP
FASP simulator.
virtual ~CbmTrdModuleSim2D()
CbmTrdModuleSim2D(Int_t mod, Int_t ly, Int_t rot, Bool_t FASP=kTRUE)
ULong64_t fTimeOld
time [ns] of the last event processed (check CbmDaq)
void SetFasp(Bool_t set=kTRUE)
Set the FEE type operating on the chamber.
CbmTrdTrianglePRF * fTriangleBinning
Integration of PRF on triangular pad-plane geometry.
Bool_t IsLabMeasurement() const
void AddDigi(Int_t address, Double_t *charge, Double_t time)
Adding triangular digits to time slice buffer.
void DumpBuffer() const
Print current buffer content.
Abstract class for module wise digitization and raw format producing.
std::shared_ptr< CbmTrdRadiator > fRadiator
Pointer to digitizer.
std::map< Int_t, std::vector< std::pair< CbmTrdDigi *, CbmMatch * > > > fBuffer
Local digits buffer as function of time for each TRD channel in the module.
Int_t fInputId
MC input file number.
Int_t fPointId
MC point id being processed.
virtual void SetPositionMC(Double_t pos[3])
Int_t fEventId
MC event id being processed.
Int_t fTimeSysOffset
Time offset of TRD digis to align them with other detectors (Bmon, ToF)
CbmTrdDigitizer * fDigitizer
virtual Int_t QueryChannel(Int_t ch) const
Query ASIC for specific pad address.
Definition of FASP channel calibration container.
static constexpr double fgkSgmCh
generic width of a pulser signal for FASP channels
Definition of FASP parameters.
virtual void Print(Option_t *opt="") const
const CbmTrdParFaspChannel * GetChannel(Int_t pad_address, UChar_t pair) const
Query the calibration for one FASP RO channel.
Describe TRD module ASIC settings (electronic gain, delays, etc)
virtual Int_t GetAsicAddress(Int_t chAddress) const
Look for the ASIC which operates on a specific channel It applies to the list of ASICs.
virtual const CbmTrdParAsic * GetAsicPar(Int_t address) const
Look for the ASIC parameters of a given DAQ id It applies to the list of ASICs.
bool GetFaspChannelPar(int pad, const CbmTrdParFaspChannel *&tilt, const CbmTrdParFaspChannel *&rect) const
Access the calibration objects describing the two FASP channels allocated to a pad....
Bool_t GetPadInfo(const Double_t *local_point, Int_t §orId, Int_t &columnId, Int_t &rowId) const
Double_t GetAnodeWireSpacing() const
Double_t GetPadSizeY(Int_t i) const
Int_t GetNofRowsInSector(Int_t i) const
Int_t GetSector(Int_t npady, Int_t &rowId) const
void ProjectPositionToNextAnodeWire(Double_t *local_point) const
Double_t GetPadSizeX(Int_t i) const
Int_t GetNofColumns() const
void TransformToLocalPad(const Double_t *local_point, Double_t &posX, Double_t &posY) const
Char_t GetPEshell(Float_t Ex) const
Get first atomic shell which can be excited by PE effect.
Double_t ScanDriftTime(Double_t y0, Double_t z0, Double_t dzdy, Double_t dy) const
Get prompt signal for track segment in the y-z plane.
Float_t GetNonIonizingBR(const Char_t shell='K') const
Get branching ration for radiative process on the.
Float_t GetBindingEnergy(const Char_t shell='K', Bool_t main=kTRUE) const
Get binding energy for the working gas.
Float_t EfCkeV(Float_t efc) const
Convert pad-plane charge in fC to energy deposit [keV] taking into account the gas gain.
Float_t EkevFC(Float_t ekev) const
Convert Energy debposit in keV to pad-plane charge taking into account the gas gain.
Double_t GetDriftTime(Double_t y0, Double_t z0) const
virtual void Print(const Option_t *opt) const
Output to screen.
Utility for converting energy to signal over the triangular pad geometry (Bucharest prototype)
Bool_t NextBinX()
Move current bin to the right.
Bool_t PrevBinX()
Move current bin to the left.
Bool_t SetOrigin(Double_t x, Double_t y)
Set map offset @ point (x,y)
@ NC
no. of neighbor columns (except the hit) to be considered in cluster definition
@ NR
no. of neighbor rows (except the hit) to be considered in cluster definition
void GoToOriginX()
Move current binx to the origin binx0.
Double_t GetChargeFraction() const
Compute charge fraction on the current bin.
void GetCurrentPad(Int_t &col, Int_t &row, Int_t &u) const
Compute the pad corresponding to current bin.
Bool_t NextBinY()
Move current bin up.
Bool_t PrevBinY()
Move current bin down.
void GoToOriginY()
Move current biny to the origin biny0.